【Java学习笔记】16:线程的协调

来源:互联网 发布:国动通信网络招聘 编辑:程序博客网 时间:2024/06/05 08:32

一个进一步的线程问题:

①空间有空闲则写入数据,否则等候空出

②若空出,通知正在等候的线程

 

三个相关方法:wait()让线程等候,notify()和notifyAll()启动等候中的线程。

 

wait()

所有实例都有一个wait set,它是一个在执行实例的wait()方法时、操作停止的线程的结核,可以看成线程的休息室。

发生以下情况之一时线程退出wait set:

①其它线程以notify或者notifyAll方法唤醒该线程

②其它线程以interrupt方法唤醒该线程

③wait方法到期

 

如在某线程中执行了obj.wait()则该线程进入obj的wait set,称为线程在obj上wait。

如在昨天学习的synchronized方法里,若调用了wait()即this.wait(),线程将进入this的wait set,这样就释放了锁定,其它线程就可以用synchronized方法了。

 

notify()

使用notify()方法时,可以从对应实例里抓出一个线程唤醒,如刚刚的两个synchronized方法和两个线程,线程A先调用了第一个同步方法,然后里面有wait()语句使线程A进入了this的wait set,然后线程A释放了锁定这样线程B又开始执行,它执行了第二个同步方法,方法里有notify()也就是this.notify(),这样就去this的wait set里找到了线程A并唤醒了。

注意,虽然线程A被唤醒了,但是线程B还握着锁定不放,因为A的作用也是去执行synchronized方法,所以这时候还是不能执行的,还是要等待线程B释放锁定。

 

补充:如果执行notify方法时,wait set里正在等候的线程不止一个,到底选择哪个线程要按照Java处理系统而异。

 

notifyAll()

obj.notifyAll()会唤醒留在实例obj的wait set里的所有线程。

 

一般在notify()和notifyAll()中选择notifyAll()。

 

以上三个方法的调用,线程必须获取调用实例的锁定,否则会抛出异常IllegalMonitorStateException。

由于所有实例都会有wait set,所以这三个方法都是Object类的方法。

 

与线程相关的其它处理(后面学):

①取消线程处理的中断

Interrupt,isInterrupted,interrupted,InterruptedException

②线程的优先级

setPriority,getPriority

③等候线程结束

Join

 

有时候线程因为某些因素无法继续进行下去,如线程A想执行synchronized方法时其他方法已经获取相同实例的锁定,线程A就无法向前推进,称为线程A有阻挡或者线程A被阻挡。

 

近期笔记参考自:中国铁道出版社《Java多线程设计模式》。

0 0
原创粉丝点击