java线程通信wait()和notify()机制

来源:互联网 发布:地图矢量化软件工具 编辑:程序博客网 时间:2024/06/06 00:08

1.案例

在网上看的视频把它总结了一下。







* 以前的资源对象保证不了,生产者生产一个数据,消费者消费一个数据,出现顺序不一致的情况,导致消费者一直消费一个数据,所以提出wait()和notify()。

//改进后的共享资源类/** * 以前的资源对象保证不了,生产者生产一个数据,消费者消费一个数据,出现顺序不一致的情况 * 导致消费者一直消费一个数据 * */public class Sourse {String name;String geneder;Boolean isEmpty=true;//添加一个判断字段,来判断资源类中是否有资源//生产者生产资源 synchronized public void push(String name ,String geneder){try{//使用WHILE段更安全,经过两次判断while(!isEmpty){//当isEmpty为FALSE的时候,不空,此时不生产,等着消费者来消费。this.wait();//当前线程释放锁,进入等待池,等待被其他线程唤醒}//=====开始生产=====this.name=name;Thread.sleep(10);//通过睡眠放大性别紊乱的问题,使用同步锁synchronized解决this.geneder=geneder;//=====结束生产=====isEmpty=false;//更改状态this.notify();//唤醒锁池中的任意一个消费者}catch(Exception e){e.printStackTrace();}}//消费者获取资源synchronized public void popup(){try{//使用WHILE段更安全,经过两次判断while(isEmpty){//当isEmpty为true的时候,为空,此时不消费,等着生产者生产。this.wait();//当前线程释放锁,进入等待池,等待被其他线程唤醒}//=====开始消费=====System.out.println(name+","+geneder);Thread.sleep(10);//通过睡眠放大性别紊乱的问题,使用同步锁synchronized解决//=====结束消费=====isEmpty=true;//更改状态this.notify();//唤醒锁池中的任意一个生产者}catch(Exception e){e.printStackTrace();}}}
在另一个CSDN的博客里看到一个特别好的关于wait(),notify()的使用和区别,稍微总结一下:

1.有synchronized的地方不一定有wait,notify

2.有wait,notify的地方必有synchronized.这是因为wait和notify不是属于线程类,而是每一个对象都具有的方法,而且,这两个方法都和对象锁有关,有锁的地方,必有synchronized。

***

wait()方法与notify()必须要与synchronized(resource)一起使用。也就是wait与notify针对已经获取了resource锁的线程进行操作,从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内。从功能上来说wait()线程在获取对象锁后,主动释放CPU控制权,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的释放操作。【因此,我们可以发现,wait和notify方法均可释放对象的锁,但wait同时释放CPU控制权,即它后面的代码停止执行,线程进入阻塞状态,而notify方法不立刻释放CPU控制权,而是在相应的synchronized(){}语句块执行结束,再自动释放锁。】释放锁后,JVM会在等待resoure的线程中选取一线程,赋予其对象锁,唤醒线程,继续执行。这样就提供了在线程间同步、唤醒的操作。Thread.sleep()与Object.wait()二者都可以暂停当前线程,释放CPU控制权,主要的区别在于Object.wait()在释放CPU同时,释放了对象锁的控制,而在同步块中的Thread.sleep()方法并不释放锁,仅释放CPU控制权。


(本段文字来自:http://blog.csdn.net/lingzhm

谢谢阅读!



原创粉丝点击