并发线程之间的协作

举报
xcc-2022 发表于 2022/07/22 11:39:37 2022/07/22
【摘要】 Java并发(五):线程之间的协作前面的笔记中提到了,当使用线程来同时运行多个任务时,可以通过使用锁(互斥)来同步两个任务,从而使得一个任务不会干涉另一个任务的资源。而当多个线程可以一起工作去解决某个问题时,如果某些部分必须在其它部分之前完成,那么就需要对线程进行协调。关于协调的一种方式join(),在笔记: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编程思想》

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。