线程的等待-通知机制


一. 前言

在之前讲到如何解决死锁问题的时候,其中有一个方法就是破坏占有且等待条件,方法中讲到是一次性申请所有资源就能解决问题,但是其中有一个点需要注意,除了那个申请到资源的线程可以继续执行外,其它线程都是只能不断地循环来判断资源是否已经释放了,这样的结果就是很多 CPU 资源都浪费在了循环判断上了。

在之前讲到如何解决死锁问题的时候,其中有一个方法就是破坏占有且等待条件,方法中讲到是一次性申请所有资源就能解决问题,但是其中有一个点需要注意,除了那个申请到资源的线程可以继续执行外,其它线程都是只能不断地循环来判断资源是否已经释放了,这样的结果就是很多 CPU 资源都浪费在了循环判断上了。

/**  
 * 获取所有资源  
 */  
synchronized boolean getAll(Object coffeeBean, Object kettle) {
     
	if (list.contains(coffeeBean) || list.contains(kettle)) {
     
		System.out.println(Thread.currentThread().getName() + " 尝试获取所有资源");  
		return false;        
	} else {
     
		list.add(coffeeBean);  
		list.add(kettle);  
		System.out.println(Thread.currentThread().getName() + " 获取咖啡豆和水壶成功!");  
	}  

	return true;  
}

// 如果没有满足条件则一直循环
while (!distributor.getAll(coffeeBean, kettle)); 

而线程中还有一个更好的解决办法,来避免无谓的循环,就是等待-通知机制。机制中会涉及到常见的 wait()notify()notifyAll()方法。

二. 等待-通知机制的简单原理

这套机制的运作方法理解起来也比较简单,就是如果一个线程申请不到资源,那就使用 wait() 方法将线程从 RUNNABLE 状态转为 WAITING 状态,也就是让线程放到对象相对应的等待队列中等待。如果这时候有一个线程完成了,就需要使用 notify() 方法来通知等待队列中的一个等待的线程移到同步队列中来接下去执行。

notifyAll()notify() 的区别就是 notifyAll() 会通知所有线程,而 notify() 只会通知其中一个,所以一般来说,推荐使用 notifyAll(),避免有的线程永远通知不到的情况发生。

三. 用等待-通知机制优化代码

将前面的例子用等待-通知机制优化后可以得到下面的代码:

public class Distributor {
     
  
    private List<Object> list = new ArrayList<>();  
  
    /**  
     * 获取所有资源  
     */  
    synchronized 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瞎叨叨的一天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值