java多线程及线程池小结
最近在学习线程池的东西,前面有篇文章《线程池的设计原则》,当然大多都是参考别人的思想。然后发现自己多线程真的写的太少了。现在来补充基础知识咯。。。
wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行.
以上是jdk api的说明,对照说明写个测试:
Code
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
ControlRunnable线程类是线程池中的具体线程,线程构造函数中调用线程的start开始线程,到run方法里得到自己的锁然后wait,等待具体的动作调用:runIt,动作调用就可以notify线程了。里边将线程要做的具体工作委托给了ThreadPoolRunnable接口,用户要使用线程池,只用将自己的任务实现此接口即可。ThreadPoolRunnable的代码如下:
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中有很多和多线程相通的地方。比如非阻塞和多线程,当然,他们不是一个意思。