- 浏览: 260505 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
zhagener:
package com.huawei.qyq.impl;imp ...
EasyMock使用说明 -
LetCode:
将String转换成InputStream -
Mr_kimilo:
MyEclipse6.5安装的时候出现问题: JS Test ...
javascript测试工具: JsTestDriver -
jersey109:
我同意楼下的,SQLException和IOException ...
check exception和uncheck exception -
jersey109:
楼主,你不说CODE,我觉得你对RuntimeExceptio ...
check exception和uncheck exception
最近在学习线程池的东西,前面有篇文章《线程池的设计原则》,当然大多都是参考别人的思想。然后发现自己多线程真的写的太少了。现在来补充基础知识咯。。。
wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行.
以上是jdk api的说明,对照说明写个测试:
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public class Test extends Thread {
@Override
public void run() {
System.out.println("before wait!");
try {
synchronized (this) {
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(20000);
} catch (Exception e) {
System.out.println("interrupted!");
}
System.out.println("after wait!");
}
public synchronized void weakup() {
this.notify();
}
}
public class Main {
public static void main(String[] args) {
Test test = new Test();
test.start();
System.out.println("shit");
try {
Thread.sleep(2000);
} catch (Exception e) {
}
test.weakup();
try {
Thread.sleep(2000);
} catch (Exception e) {
}
test.interrupt();
System.out.println("shit");
}
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public class Test extends Thread {
@Override
public void run() {
System.out.println("before wait!");
try {
synchronized (this) {
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(20000);
} catch (Exception e) {
System.out.println("interrupted!");
}
System.out.println("after wait!");
}
public synchronized void weakup() {
this.notify();
}
}
public class Main {
public static void main(String[] args) {
Test test = new Test();
test.start();
System.out.println("shit");
try {
Thread.sleep(2000);
} catch (Exception e) {
}
test.weakup();
try {
Thread.sleep(2000);
} catch (Exception e) {
}
test.interrupt();
System.out.println("shit");
}
wait和notify针对的是对象,而不是线程。因为这两个方法都是Object的方法。与线程无关。
所有的线程结束之后,程序才会结束。此处如果不sleep的话,有可能weakup会早于wait先调用。
执行interrupt()时,并不需要获取Thread实例的锁定.任何线程在任何时刻,都可以调用其他线程interrupt().当sleep中的线程被调用interrupt()时,就会放弃暂停的状态.并抛出InterruptedException.
interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。
如果线程没有被阻塞,这时调用interrupt()将不起作用;否则,线程就将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。
线程A在执行sleep,wait,join时,线程B调用A的interrupt方法,的确这一个时候A会有InterruptedException异常抛出来.但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException。
如果线程A正在执行一些指定的操作时如赋值,for,while,if,调用方法等,都不会去检查中断状态,所以线程A不会抛出InterruptedException,而会一直执行着自己的操作.当线程A终于执行到wait(),sleep(),join()时,才马上会抛出InterruptedException.
若没有调用sleep(),wait(),join()这些方法,或是没有在线程里自己检查中断状态自己抛出InterruptedException的话,那
InterruptedException是不会被抛出来的.
下面再看tomcat的线程池就比较清楚了:
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->class ControlRunnable implements Runnable {
ThreadPool p;
Thread t;
ThreadPoolRunnable toRun;
boolean shouldTerminate;
boolean shouldRun;
boolean noThData;
Object thData[] = null;
ControlRunnable(ThreadPool p) {
toRun = null;
shouldTerminate = false;
shouldRun = false;
this.p = p;
t = new Thread(this);
t.start();
noThData = true;
thData = null;
}
public void run() {
while (true) {
try {
synchronized (this) {
if (!shouldRun && !shouldTerminate) {
this.wait();
}
}
if (shouldTerminate) {
break;
}
try {
if (noThData) {
thData = toRun.getInitData();
noThData = false;
}
if (shouldRun) {
toRun.runIt(thData);
}
} catch (Throwable t) {
System.err.println("ControlRunnable Throwable: ");
t.printStackTrace();
shouldTerminate = true;
shouldRun = false;
p.notifyThreadEnd();
} finally {
if (shouldRun) {
shouldRun = false;
p.returnController(this);
}
}
if (shouldTerminate) {
break;
}
} catch (InterruptedException ie) {
}
}
}
public synchronized void runIt(ThreadPoolRunnable toRun) {
if (toRun == null) {
throw new NullPointerException("No Runnable");
}
this.toRun = toRun;
shouldRun = true;
this.notify();
}
public synchronized void terminate() {
shouldTerminate = true;
this.notify();
}
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->class ControlRunnable implements Runnable {
ThreadPool p;
Thread t;
ThreadPoolRunnable toRun;
boolean shouldTerminate;
boolean shouldRun;
boolean noThData;
Object thData[] = null;
ControlRunnable(ThreadPool p) {
toRun = null;
shouldTerminate = false;
shouldRun = false;
this.p = p;
t = new Thread(this);
t.start();
noThData = true;
thData = null;
}
public void run() {
while (true) {
try {
synchronized (this) {
if (!shouldRun && !shouldTerminate) {
this.wait();
}
}
if (shouldTerminate) {
break;
}
try {
if (noThData) {
thData = toRun.getInitData();
noThData = false;
}
if (shouldRun) {
toRun.runIt(thData);
}
} catch (Throwable t) {
System.err.println("ControlRunnable Throwable: ");
t.printStackTrace();
shouldTerminate = true;
shouldRun = false;
p.notifyThreadEnd();
} finally {
if (shouldRun) {
shouldRun = false;
p.returnController(this);
}
}
if (shouldTerminate) {
break;
}
} catch (InterruptedException ie) {
}
}
}
public synchronized void runIt(ThreadPoolRunnable toRun) {
if (toRun == null) {
throw new NullPointerException("No Runnable");
}
this.toRun = toRun;
shouldRun = true;
this.notify();
}
public synchronized void terminate() {
shouldTerminate = true;
this.notify();
}
ControlRunnable线程类是线程池中的具体线程,线程构造函数中调用线程的start开始线程,到run方法里得到自己的锁然后wait,等待具体的动作调用:runIt,动作调用就可以notify线程了。里边将线程要做的具体工作委托给了ThreadPoolRunnable接口,用户要使用线程池,只用将自己的任务实现此接口即可。ThreadPoolRunnable的代码如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public interface ThreadPoolRunnable {
public Object[] getInitData();
public void runIt(Object thData[]);
}
public Object[] getInitData();
public void runIt(Object thData[]);
}
另外,ThreadPool本身还运行了一个MonitorRunnable的线程,用来管理线程池。当(currentThreadCount - currentThreadsBusy) > maxSpareThreads,就会调用ControlRunnable类的terminate方法删除空闲线程,准备删除的线程是否空闲是通过shouldTerminate参数来判断。线程池采用Vector来存储当前空闲的线程。
接下来回去研究java nio包。网络编程也是自己一直都想去系统的学习的东西。而且,在java nio中有很多和多线程相通的地方。比如非阻塞和多线程,当然,他们不是一个意思。
发表评论
-
类的初始化顺序
2010-03-30 09:28 898我们大家都知道,对于静态变量、静态初始化块、变量、初始化块、构 ... -
java static 变量
2010-03-30 09:27 1165有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。 ... -
Java中的构造器(构造方法)的调用
2010-03-30 09:21 1378注意:(1)在子类中的 ... -
java学习中重写与重载方法的区别
2010-03-30 09:17 1433重写的主要优点是能 ... -
收集到的java 正则验证
2010-01-12 13:02 1109import java.util.regex.*; ... -
Apache StringUtils api 中文 英文 对
2010-01-08 11:23 3104StringUtils api 中文 英文 对照 ... -
MyEclipse 7.0 Milestone-1破解
2010-01-05 15:36 1394import java.io.Buffered ... -
JDK中的URLConnection参数详解
2009-12-25 14:50 9652009年07月10日 16:52 针对JDK中 ... -
java 中int String类型转换
2009-12-15 17:08 1659int -> String int i=12345;S ... -
@suppresswarnings
2009-12-03 12:02 1585about @SuppressWarnings. 关键字: ... -
JDK动态代理的简单使用示例
2009-11-17 10:00 1088JDK动态代理的简单使用示例: 如有业务类:package ... -
CGlib简单介绍
2009-11-17 09:59 1091CGlib概述:cglib(Code Generation L ... -
java(Web)中相对路径,绝对路径问题
2009-11-12 17:23 11291.基本概念的理解 绝对路径:绝对路径就是你的主页上的文件 ... -
J2EE项目异常处理
2009-10-23 16:12 973为什么要在J2EE项目 ... -
Java优化编程--核心类与性能 I/O流
2009-10-23 15:34 1655Java 的I/O流给我的感觉 ... -
URLConnection ,获取互联网资源
2009-10-23 15:32 1032这段代码将向你介绍几个比较常见但需要注意的问题: ... -
Java Exception 处理之最佳实践
2009-10-23 15:31 776本文是Exception处理的一篇不错的文章,从Java Ex ... -
java 异常Exception
2009-10-22 11:26 1160异常处理是程序设计中 ... -
check exception和uncheck exception
2009-10-22 11:15 6193使用Checked Exception还是UnChecked ... -
java之classloader体系结构(含hotswap)
2009-10-15 15:40 1256jvm classLoader architecture : ...
相关推荐
### Java多线程小结 #### 一、多线程的概念与意义 多线程是Java编程中的一个重要概念,指的是程序在运行时可以同时执行多个线程的能力。它能够提高程序的性能,尤其是在多核处理器的环境下。多线程使得程序能够更...
Java线程池是一种高效管理线程的技术,它允许开发者预定义一组线程,根据任务的需要灵活调度,而不是每次需要执行任务时都创建新的线程。这种设计模式大大提高了系统的性能,减少了系统资源的消耗,特别是在高并发...
### Java多线程设计模式详解 #### 一、Java多线程基础 Java语言自诞生以来,便内置了对多线程的支持。多线程能够让程序在同一时间处理多个任务,提高程序的执行效率和响应速度。Java中创建线程有两种基本方式: 1...
八、线程同步小结 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:volatile关键字 Java线程:新特征-线程池 一、固定大小的线程池 二、单任务线程池 三、可变尺寸的线程池 四、延迟连接池 五、...
- **线程安全的集合类**:如`ConcurrentHashMap`、`CopyOnWriteArrayList`等,设计用于多线程环境。 - **原子类(Atomic*)**:如`AtomicInteger`、`AtomicLong`,提供原子操作,常用于实现无锁编程。 7. **线程...
目录网盘文件永久链接 01课程安排av 02什么是并发和并行av ...08线程创建小结av 09线程生命周期avi 10.线程安全问题什么是线程安全avi 11线程安全同题问题分析avi 12线程安全问题线程安全问题演示avi ...............
在实际项目中,"Android异步加载图像小结 (含线程池,缓存方法).doc"文档可能详细介绍了这些技术的实现细节和案例,而"项目说明.zip"可能包含了具体实现的代码示例,供开发者参考学习。 总的来说,高效地在...
在Android应用开发中,图像加载是一个常见的...以上就是关于“Android异步加载图像小结(含线程池,缓存方法)”的主要知识点。在实际应用中,开发者应结合项目需求,合理选择和优化这些技术,以提供流畅的用户体验。
- 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。在Android中,可以使用Java的ExecutorService和ThreadPoolExecutor来创建线程池,控制并发量,防止过度创建线程...
线程池可以高效地管理和调度多个线程,避免频繁创建销毁线程带来的开销。 2. **Java并发库中的ExecutorService**:Java提供了`ExecutorService`接口,它是线程池的实现。我们可以使用`Executors`类提供的工厂方法来...
线程池是多线程编程中的一个优秀实践,它通过预先创建并维护一定数量的工作线程来避免频繁创建和销毁线程带来的开销。在Android中,我们可以使用`java.util.concurrent`包下的`ExecutorService`接口及其实现类来创建...