Java并发(五):线程之间的协作

Java并发(五):线程之间的协作

前面的笔记中提到了,当使用线程来同时运行多个任务时,可以通过使用锁(互斥)来同步两个任务,从而使得一个任务不会干涉另一个任务的资源。而当多个线程可以一起工作去解决某个问题时,如果某些部分必须在其它部分之前完成,那么就需要对线程进行协调
关于协调的一种方式join(),在笔记:Java并发(二):基本线程机制之再续前缘中有使用方式的介绍。接下来介绍的是线程之间协调的其他方式。

一、wait()、notify()和notifyAll()
调用wait()使得线程等待某个条件满足,线程在等待时被挂起,当其他线程的运行使得这个条件满足时,其它线程会调用notify()或者notifyAll()来换线挂起的线程
wait()、notify()和notifyAll()都是属于Object的一部分,而不是属于Thread。并且只能用在同步方法或者同步控制块中,否则在运行时会抛出IllegalMnitorStateException。
使用wait()挂起期间,线程会释放锁。这是因为,如果没有释放锁,那么其它线程就无法进入对象的同步方法或者同步控制块中,也就无法执行notify()或者notifyAll()来唤醒挂起的线程,造成死锁。
在这里插入图片描述
Ps:wait()方法可以指定线程的等待时间。因此时间到期之后,线程也会恢复
wait()和sleep()的区别:
 wait()是Object的方法,sleep()是Thread的静态方法。
wait()会释放锁,而sleep()不会
在这里插入图片描述
值得一提的是,join()是通过wait()来实现的,因此使用join()也能够释放锁
notify()和notifyAll()的区别:
对于多个任务的单个对象处于wait()状态,调用notifyAll()方法比调用notify()方法更安全。notify()方法在众多等待同一个锁的任务中只有一个会被唤醒,因此除非能够保证被唤醒的是恰当的任务(例如所有任务等待相同的条件),否则由于线程调度机制的非确定性,可能会导致死锁。而notifyAll()则是唤醒所有等待同一个锁的所有任务
而事实上,notifyAll()真正唤醒的是等待该条件的任务,并非所有任务
在这里插入图片描述

二、await()、signal()以及signalAll()
Java SE5的java.util.concurrent类库中提供了Condition类来实现线程之间的协作,可以在Condition上调用await()方法使线程等待,其它线程调用signal()或signalAll()方法唤醒等待的线程
相比于wait()这种等待方式,await()可以指定等待的条件,因此更加灵活。
在这里插入图片描述

参考资料:《Java编程思想》
CS-Notes/Java 并发.md

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值