为什么wait()、notify()方法需要和synchronized一起使用
提示:更多优秀博文请移步博主的GitHub仓库:GitHub学习笔记、Gitee学习笔记
Obj.wait()与Obj.notify()必须要与synchronized(Obj)一起使用,也就是wait,与notify必须通过获取的锁对象进行调用**,从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){…}语句块内。从功能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。相应的notify()就是对对象锁的唤醒操作。
1. 不一起使用导致的后果
public class Haha {
public Map<String,String> map=new HashMap<>();
public void haha() throws InterruptedException {
synchronized (map){//使用map加锁
System.out.println("haha method is run");
this.wait();//用当前对象,调用wait方法会报错;正确的写法是map.wait()
}
}
}
public class Test {
public static void main(String[] args) {
new Thread(()->{
try {
new Haha().haha();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
在上述代码中由于Haha类的haha方法中使用map加的锁,但又试图使用this.wait方法释放锁此时会报错:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PMmhumDw-1585273461081)(…/images/7.png)]
2. 为什么要在一起使用
Object.wait(),Object.notify(),Object.notifyAll()都是Object的方法,换句话说,就是每个类里面都有这些方法。
- Object.wait():释放当前对象锁,并进入阻塞队列
- Object.notify():唤醒当前对象阻塞队列里的任一线程(并不保证唤醒哪一个)
- Object.notifyAll():唤醒当前对象阻塞队列里的所有线程
为什么这三个方法要与synchronized一起使用呢?解释这个问题之前,我们先要了解几个知识点
- 每一个对象都有一个与之对应的监视器
- 每一个监视器里面都有一个该对象的锁以及一个等待队列和一个同步队列
wait()方法的语义有两个,一是释放当前对象锁,另一个是进入阻塞队列,可以看到,这些操作都是与监视器相关的,当然要指定一个监视器才能完成这个操作了
notify()方法也是一样的,用来唤醒一个线程,你要去唤醒,首先你得知道他在哪儿,所以必须先找到该对象,也就是获取该对象的锁,当获取到该对象的锁之后,才能去该对象的对应的等待队列去唤醒一个线程。值得注意的是,只有当执行唤醒工作的线程离开同步块,即释放锁之后,被唤醒线程才能去竞争锁。
因wait()而导致阻塞的线程是放在阻塞队列中的,因竞争失败导致的阻塞是放在同步队列中的,notify()/notifyAll()实质上是把阻塞队列中的线程放到同步队列中去
为了便于理解,你可以把线程想象成一个个列车,对象想象成车站,每一个车站每一次能跑一班车,这样理解起来就比较容易了。
值得提的一点是,synchronized是一个非公平的锁,如果竞争激烈的话,可能导致某些线程一直得不到执行。
参考文章:https://blog.csdn.net/qq_39907763/article/details/79301813
为什么wait()、notify()方法需要和synchronized一起使用的更多相关文章
- java 多线程:线程通信-等待通知机制wait和notify方法;(同步代码块synchronized和while循环相互嵌套的差异);管道通信:PipedInputStream;PipedOutputStream;PipedWriter; PipedReader
1.等待通知机制: 等待通知机制的原理和厨师与服务员的关系很相似: 1,厨师做完一道菜的时间不确定,所以厨师将菜品放到"菜品传递台"上的时间不确定 2,服务员什么时候可以取到菜,必 ...
- java多线程详解(6)-线程间的通信wait及notify方法
Java多线程间的通信 本文提纲 一. 线程的几种状态 二. 线程间的相互作用 三.实例代码分析 一. 线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种:(1). 产生(New) ...
- Java 多线程(七) 线程间的通信——wait及notify方法
线程间的相互作用 线程间的相互作用:线程之间需要一些协调通信,来共同完成一件任务. Object类中相关的方法有两个notify方法和三个wait方法: http://docs.oracle.com/ ...
- Java使用wait() notify()方法操作共享资源
Java多个线程共享资源: 1)wait().notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写. 2)调用某个对象的wait()方法能让当前线程阻塞,并且当前线 ...
- 并发编程之 wait notify 方法剖析
前言 2018 元旦快乐. 摘要: notify wait 如何使用? 为什么必须在同步块中? 使用 notify wait 实现一个简单的生产者消费者模型 底层实现原理 1. notify wait ...
- Java中wait()和notify()方法的使用
1. wait方法和notify方法 这两个方法,包括notifyAll方法,都是Object类中的方法.在Java API中,wait方法的定义如下: public final void wait( ...
- Java使用wait() notify()方法操作共享资源详解_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 Java多个线程共享资源: 1)wait().notify()和notifyAll()方法是本地方法,并且为final方 ...
- wait/notify方法
执行wait方法会释放锁,执行notify不会释放锁 package com.qf.test05.pojo; /** * @author qf * @create 2018-09-18 10:41 * ...
- 从Guarded Block来看Java中的wait和notify方法
目录 预备知识 概览 线程同步 wait()方法 wait() wait(long timeout) wait(long timeout, int nanos) notify() & noti ...
- 为什么Java中 wait 方法需要在 synchronized 的方法中调用?
另一个棘手的核心 Java 问题,wait 和 notify.它们是在有 synchronized 标记的方法或 synchronized 块中调用的,因为 wait 和 modify 需要监视对其上 ...
随机推荐
- Godot Label样式 Textrue纹理,实现样式修改,背景填充
目录 前言 运行环境 新建项目 Style 样式讲解 StyleBoxEmpty:普通样式 StyleBoxTexture:字体样式 StyleBoxFlat:填充样式 StyleBoxLine:行样 ...
- c# TryParse
c# tryparse和parse对比,大体内容是一致的. parse 会返回异常,主要表现为三种. 第一种ArgumentNullException,这里面表示,为空. 第二种formatexcep ...
- Ajax 原理是什么?如何实现?
一.是什么 AJAX全称(Asynchronous Javascript And XML) 即异步的JavaScript 和XML,是一种创建交互式网页应用的网页开发技术,可以在不重新加载整个网页的情 ...
- CF-938(C-E)
CF-938 C 没啥好分析的,就记录一下我因为没有清空s[n+1].上取整写成了下取整卡了一个多小时(╬▔皿▔)╯ const int N=2e5+5; int a[N],p[N],s[N]; vo ...
- JavaServlet类
"感谢您阅读本篇博客!如果您觉得本文对您有所帮助或启发,请不吝点赞和分享给更多的朋友.您的支持是我持续创作的动力,也欢迎留言交流,让我们一起探讨技术,共同成长!谢谢!" 介绍Ser ...
- KubeVela 1.5:灵活框选 CNCF 原子能力打造独特的企业应用发布平台
简介: KubeVela 1.5 于近日正式发布.在该版本中为社区带来了更多的开箱即用的应用交付能力,包括新增系统可观测:新增 Cloud Shell 终端,将 Vela CLI 搬到了浏览器:增强的 ...
- 关于CDN的原理、术语和应用场景那些事
关于CDN,想必你一定看过很多官方的解释.今天,CDN百科第七期,将用一篇3844字的文章,来带你了解CDN的诞生.术语.原理.特征以及应用场景,看完这篇文章,相信你将会对CDN这项互联网基础设施有更 ...
- 阿里云消息队列 RocketMQ 5.0 全新升级:消息、事件、流融合处理平台
简介: RocketMQ5.0 的发布标志着阿里云消息从消息领域正式迈向了"消息.事件.流"场景大融合的新局面.未来阿里云消息产品的演进也将继续围绕消息.事件.流核心场景而开展. ...
- win10 uwp 使用 XamlTreeDump 获取 XAML 树元素内容
本文来安利大家 XamlTreeDump 库,通过这个库可以将 XAML 树上的元素转换为 json 字符串,可以用来进行 UI 单元测试 开始之前先通过 NuGet 工具安装 XamlTreeDum ...
- 2019-9-2-C#-设计模式-责任链
title author date CreateTime categories C# 设计模式 责任链 lindexi 2019-09-02 12:57:37 +0800 2018-2-13 17:2 ...