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

本文详细介绍了Java中线程同步的重要机制wait()和notify(),并通过一个具体的生产者-消费者模型示例,展示了如何利用这些方法确保线程间的正确同步。文章还解释了wait()与notify()方法的使用细节及其与synchronized关键字的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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();
		}	
	}
}
在另一个优快云的博客里看到一个特别好的关于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.youkuaiyun.com/lingzhm

谢谢阅读!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值