Java并发(二十一)----wait notify介绍
1、小故事 - 为什么需要 wait
由于条件不满足(没烟干不了活啊,等小M把烟送过来),小南不能继续进行计算
但小南如果一直占用着锁,其它人就得一直阻塞,效率太低

于是老王单开了一间休息室(调用 wait 方法),让小南到休息室(WaitSet)等着去了,但这时锁释放开,其它人可以由老王随机安排进屋
直到小M将烟送来,大叫一声 [ 你的烟到了 ] (调用 notify 方法)

小南于是可以离开休息室,重新进入竞争锁的队列

2、wait notify 原理

Owner 线程发现条件不满足,调用 wait 方法,即可进入 WaitSet 变为 WAITING 状态
BLOCKED 和 WAITING 的线程都处于阻塞状态,不占用 CPU 时间片
BLOCKED 线程会在 Owner 线程释放锁时唤醒
WAITING 线程会在 Owner 线程调用 notify 或 notifyAll 时唤醒,但唤醒后并不意味者立刻获得锁,仍需进入 EntryList 重新竞争
3、API 介绍
obj.wait()让进入 object 监视器的线程到 waitSet 等待obj.notify()在 object 上正在 waitSet 等待的线程中挑一个唤醒obj.notifyAll()让 object 上正在 waitSet 等待的线程全部唤醒
它们都是线程之间进行协作的手段,都属于 Object 对象的方法。必须获得此对象的锁,才能调用这几个方法,否则会报IllegalMonitorStateException
final static Object obj = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (obj) {
log.debug("执行....");
try {
obj.wait(); // 让线程在obj上一直等待下去
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("其它代码....");
}
}).start();
new Thread(() -> {
synchronized (obj) {
log.debug("执行....");
try {
obj.wait(); // 让线程在obj上一直等待下去
} catch (InterruptedException e) {
e.printStackTrace();
}
log.debug("其它代码....");
}
}).start();
// 主线程两秒后执行
sleep(2);
log.debug("唤醒 obj 上其它线程");
synchronized (obj) {
obj.notify(); // 唤醒obj上随机一个线程
// obj.notifyAll(); // 唤醒obj上所有等待线程
}
}
notify 的一种结果
20:00:53.096 [Thread-0] c.TestWaitNotify - 执行....
20:00:53.099 [Thread-1] c.TestWaitNotify - 执行....
20:00:55.096 [main] c.TestWaitNotify - 唤醒 obj 上其它线程
20:00:55.096 [Thread-0] c.TestWaitNotify - 其它代码....
notifyAll 的结果
19:58:15.457 [Thread-0] c.TestWaitNotify - 执行....
19:58:15.460 [Thread-1] c.TestWaitNotify - 执行....
19:58:17.456 [main] c.TestWaitNotify - 唤醒 obj 上其它线程
19:58:17.456 [Thread-1] c.TestWaitNotify - 其它代码....
19:58:17.456 [Thread-0] c.TestWaitNotify - 其它代码....
wait() 方法会释放对象的锁,进入 WaitSet 等待区,从而让其他线程就机会获取对象的锁。无限制等待,直到 notify 为止
wait(long n) 有时限的等待, 到 n 毫秒后结束等待,或是被 notify
Java并发(二十一)----wait notify介绍的更多相关文章
- Java并发(十一):Condition条件
先做总结: 1.为什么使用Condition条件? synchronized配合Object的wait().notify()系列方法可以实现等待/通知模式. Lock提供了条件Condition,对线 ...
- 006 Java并发编程wait、notify、notifyAll和Condition
原文https://www.cnblogs.com/dolphin0520/p/3920385.html#4182690 Java并发编程:线程间协作的两种方式:wait.notify.notifyA ...
- Java并发(二):基础概念
并发编程的第二部分,先来谈谈发布(Publish)与逸出(Escape); 发布是指:对象能够在当前作用域之外的代码中使用,例如:将对象的引用传递到其他类的方法中,对象的引用保存在其他类可以访问的地方 ...
- Java并发包下锁学习第二篇Java并发基础框架-队列同步器介绍
Java并发包下锁学习第二篇队列同步器 还记得在第一篇文章中,讲到的locks包下的类结果图吗?如下图: 从图中,我们可以看到AbstractQueuedSynchronizer这个类很重要(在本 ...
- Java并发:ThreadLocal的简单介绍
作者:汤圆 个人博客:javalover.cc 前言 前面在线程的安全性中介绍过全局变量(成员变量)和局部变量(方法或代码块内的变量),前者在多线程中是不安全的,需要加锁等机制来确保安全,后者是线程安 ...
- Java 并发专题 : Executor详细介绍 打造基于Executor的Web服务器
转载标明出处:http://blog.csdn.net/lmj623565791/article/details/26938985 继续并发,貌似并发的文章很少有人看啊~哈~ 今天准备详细介绍java ...
- Java 并发专题 : Executor具体介绍 打造基于Executor的Webserver
转载标明出处:http://blog.csdn.net/lmj623565791/article/details/26938985 继续并发,貌似并发的文章非常少有人看啊~哈~ 今天准备具体介绍jav ...
- 菜鸟学Java(二十一)——怎样更好的进行单元測试——JUnit
測试在软件生命周期中的重要性,不用我多说想必大家也都很清楚.软件測试有许多分类,从測试的方法上可分为:黑盒測试.白盒測试.静态測试.动态測试等:从软件开发的过程分为:单元測试.集成測试.确认測试.验收 ...
- Java并发编程-volatile可见性的介绍
要学习好Java的多线程,就一定得对volatile关键字的作用机制了熟于胸.最近博主看了大量关于volatile的相关博客,对其有了一点初步的理解和认识,下面通过自己的话叙述整理一遍. 有什么用? ...
- 菜鸟学Java(二十一)——如何更好的进行单元测试——JUnit
测试在软件生命周期中的重要性,不用我多说想必大家也都非常清楚.软件测试有很多分类,从测试的方法上可分为:黑盒测试.白盒测试.静态测试.动态测试等:从软件开发的过程分为:单元测试.集成测试.确认测试.验 ...
随机推荐
- MySQL高级10-InnoDB引擎存储架构
一.逻辑存储结构 表空间(Tablespace):一个mysql实例,及一个数据库实例,可以对应多个表空间(ibd文件),用于存储记录,索引等数据. 段(Segment):分为数据段(Leaf nod ...
- Solution -「ZJOI 2014」力
Descrption Link. 对于每一个 \(i\),求出: \[\sum_{j=1}^{i-1}\frac{a_{j}}{(i-j)^{2}}-\sum_{j=i+1}^{n}\frac{a_{ ...
- TCP vs UDP:揭秘可靠性与效率之争
概述 今天我们开始主要讲解TCP的相关知识点.在之前讲解分层章节的时候,我们提到过一个重要观点.在网络层及以下几层,更多的是让主机与主机建立连接,也就是说你的电脑需要知道另一台电脑在哪里才能连接上它. ...
- 对某个接口进行限流 以 Aop 注解的形式绑定接口 用redis实现
简单的针对某个接口进行限流,如果需要整体限流的话还是建议在网关上面或者服务器上面动手Controller: @LimitRequest(count = 1,time = 60 * 1000 * 2) ...
- 用Rust手把手编写一个Proxy(代理), TLS加密通讯
用Rust手把手编写一个Proxy(代理), TLS加密通讯 项目 ++wmproxy++ gite: https://gitee.com/tickbh/wmproxy github: https:/ ...
- Vue2系列(lqz)——Vue介绍
文章目录 Vue入门 零:前端目前形势 前端的发展史 一:Vue介绍 和 基本使用 1.Vue介绍 渐进式框架 网站 2.Vue特点 易用 灵活 高效 3.M-V-VM思想 ① MVVM介绍 ② MV ...
- git Failed to connect to 127.0.0.1 port xxxx: Connection refused 的问题。
问题描述在使用 git 拉取.提交代码的时候,会出现 git Failed to connect to 127.0.0.1 port xxxx: Connection refused 的问题. 原因: ...
- 【Unity3D】UI Toolkit容器
1 前言 UI Toolkit简介 中介绍了 UI Builder.样式属性.UQuery.Debugger,UI Toolkit元素 中介绍了 Label.Button.TextField.To ...
- vscode双击没反应,后台也看不到进程的解决方案
百度找的解决方案: cmd窗口执行 netsh winsock reset 重置命令. 删除Romaing下的Code文件夹 修改Code/User/locale.json(我没找到这个文件)中的&q ...
- postgresql 最近优化的SQL集合案例、(不写过程了只记录案例,PG优化器问题还是不少)
案例1: -- 原SQL + 执行计划: explain analyze SELECT G.PID, G.FLOW_ID, G.STATUS, G.ID, AAAAAA.INFO_ID, G.CREA ...