wait()、notify、notifyAll()的使用
wait()、notify、notifyAll()的使用
参考:https://www.jianshu.com/p/25e243850bd2?appinstall=0
一)、java 中对象锁的模型
JVM会为一个使用内部锁(synchronized)的对象维护两个集合,Entry Set和Wait Set,即锁池和等待池。
二)、Entry Set:*
如果线程A已经持有了对象锁,此时如果有其他线程也想获得该对象锁的话,它只能进入Entry Set,并且处于线程的BLOCKED状态。
可能进入Entey Set的线程:
1).两个抢夺cpu的线程未抢夺到的一方。
2).notify()/notifyAll()唤醒却未抢夺到cpu的线程。
三)、Wait Set:
如果线程A调用了wait()方法,那么线程A会释放该对象的锁,进入到Wait Set,并且处于线程的WAITING状态。
可能进入wait状态的线程:
1).调用wait()方法。
四)、Runnable状态的转变
Entry Set中的线程的状态为Blocked状态:
1).当对象锁被释放的时候,JVM会唤醒处于Entry Set中的某一个线程,这个线 程的状态就从BLOCKED转变为RUNNABLE。
Wait Set中的线程状态为Waiting状态:
1) .当对象的notify()方法被调用时,JVM会唤醒处于Wait Set中的某一个线程,这个线程的状态就从WAITING转变为RUNNABLE。
2).当notifyAll()方法被调用时,Wait Set中的全部线程会转变为RUNNABLE状态。所有Wait Set中被唤醒的线程会被转移到Entry Set中。
注:只有处于Runnable状态的线程才能去竞争锁,获取资源。
五)、notify()和notifyAll()的区别
notify()只唤醒一个线程,notifyAll()唤醒Wati Set的所有线程。
六)、使用notify()容易发生死锁状态
举例:生产者和消费者线程
消费一进行消费,判断buff为空,调用wait()进入等待状态,消费者二进行消费buff为空,调用wait(),进入等待状态,生产者一进行生产,buff满,notify()消费者一,此时生产者二在Entry Set中抢夺到资源,判断buff满,进入到wait状态,消费者一消费资源,notify(),如果唤醒了生产者,继续生产,若此时生产者一退出了生产,唤醒了消费者二,buffer为空,消费者二进入wait状态,此时,生产者二和消费者都进入等待状态,没有Runable状态的线程,生产者2和消费者2在Wait Set中互相等待,发生死锁。
注: 具体代码参考https://www.jianshu.com/p/25e243850bd2?appinstall=0
七)、wait()、notify、notifyAll()要配合synchonized使用
解释一下,这里为什么配合synchonized:
1).如果线程要调用对象的wait()方法,必须首先获得该对象的监视器锁,调用
wait()之后当前线程又立即释放掉锁,线程随后进入WAIT_SET(等待池)中。
2).如果线程要调用对象的notify()/notifyAll()方法,也必须先获得对象的 监视器锁调用方法之后,立即释放掉锁然后处于Wait_set的线程被转移到 Entry_set(等锁 池)中去竞争锁资源.。The Winner Thread,也就是 成功获得了对象的锁的线程,就是对象锁的拥有者,会进入runnable状态。
3).由于需要获得锁之后才能够调用wait()/notify()方法,因此必须将它们放 到同步代码块中.
八)、总结
1).Jvm的内部锁对象(synchonized)维护两个集合Entry Set 和 Wait Set。
2).未抢占到cpu资源或被唤醒却未抢占到cpu资源的线程会放置在Entry Set中。
3).调用wait()方法的线程进入Wait Set。
4).Entry Set集合的线程为Blocked状态,Wait Set集合中的线程为Waiting状态。
5).当锁资源被释放时,Entry Set的某一个线程状态会变成Runnable状态。
6).当调用notify()方法时,Wait Set的的某一线程被唤醒,由waiting状态转为Runable状态,调用 notifyAll()时,Wait Set的所有线程都被唤醒,线程状态由waiting转为Runable状态,并移入Entry Set中。
wait()、notify、notifyAll()的使用的更多相关文章
- java 多线程之wait(),notify,notifyAll(),yield()
wait(),notify(),notifyAll()不属于Thread类,而是属于Object基础类,也就是说每个对像都有wait(),notify(),notifyAll()的功能.因为都个对像都 ...
- java中的wait(),notify(),notifyAll(),synchronized方法
wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法.意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了.这三个方法 ...
- java 多线程(wait/notify/notifyall)
package com.example; public class App { /* wait\notify\notifyAll 都属于object的内置方法 * wait: 持有该对象的线程把该对象 ...
- Java多线程8:wait()和notify()/notifyAll()
轮询 线程本身是操作系统中独立的个体,但是线程与线程之间不是独立的个体,因为它们彼此之间要相互通信和协作. 想像一个场景,A线程做int型变量i的累加操作,B线程等待i到了10000就打印出i,怎么处 ...
- 使用Object的wait,notify,notifyAll做线程调度
我们知道java中的所有类的祖先都是Object,Object类有四个个方法wait(),wait(long timeout),notify(),notifyAll(),这四个方法可以用来做线程的调度 ...
- Java多线程之wait(),notify(),notifyAll()
在多线程的情况下,因为同一进程的多个线程共享同一片存储空间,在带来方便的同一时候,也带来了訪问冲突这个严重的问题.Java语言提供了专门机制以解决这样的冲突,有效避免了同一个数据对象被多个线程同一时候 ...
- Java多线程的wait(),notify(),notifyAll()
在多线程的情况下.因为多个线程与存储空间共享相同的过程,同时带来的便利.它也带来了访问冲突这个严重的问题. Java语言提供了一种特殊的机制来解决这类冲突,避免同一数据对象由多个线程在同一时间访问. ...
- Java多线程学习之wait、notify/notifyAll 详解
1.wait().notify/notifyAll() 方法是Object的本地final方法,无法被重写. 2.wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关 ...
- 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型
关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...
- Java多线程:wait(),notify(),notifyAll()
1. wait(),notify(),notifyAll() 2. wait() 2.1. wait() 2.2. wait(long timeout) 2.3. wait(long timeout, ...
随机推荐
- 百万年薪python之路 -- MySQL数据库之 常用数据类型
MySQL常用数据类型 一. 常用数据类型概览 # 1. 数字: 整型: tinyint int bigint 小数: float: 在位数比较短的情况下不精确 double: 在位数比较长的情况下不 ...
- 设计模式(七)Builder模式
Builder模式,从这个名字我们可以看出来,这种设计模式就是用于组装具有复杂结构的实例的. 下面还是以一个实例程序来解释这种设计模式,先看实例程序的类图. 这里为了调试方便,只实现其中一个功能Tex ...
- StackView在Android的应用
StackView是AdapterViewAnimator的子类,它用于显示Adapter提供的一系列View.StackView将会以“堆叠”的方式来显示多个列表项.为了控制StackView现实的 ...
- 图数据库PageRank算法
目录: 定义 计算原理 定义: 假设对象A具有指向它的对象T1 ... Tn.参数d是阻尼系数,取值范围在0和1之间,通常将d设置为0.85.C(A)被定义为从对象A出去的连接数. 对象A的PageR ...
- PhpStudy2018后门漏洞预警及漏洞复现&检测和执行POC脚本
PhpStudy2018后门漏洞预警及漏洞复现&检测和执行POC脚本 phpstudy介绍 Phpstudy是国内的一款免费的PHP调试环境的程序集成包,其通过集成Apache.PHP.MyS ...
- os模块操作文件
os模块: path=os.path.join(os.path.dirname(os.path.dirname(__file__)),'images') path:运行脚本的当前文件下的上一个文件的地 ...
- 网络安全-主动信息收集篇第二章-三层网络发现之nmap和fping和Hping
nmap IP -sn nmap当目标IP在同一网段时,nmap会发送ARP包,当目标IP不在同一网段时nmap会发送ICMP的包. fping IP fping -g 参数支持对IP地址起始和结 ...
- [考试反思]0929csp-s模拟测试55:消逝
菜得过分. 面对T1的大板子不知所措,然后T2的贪心不小心把排序语句删了... T1这种大模板啊...其实我是觉得我能打出来的,然后先用一个小时码了一个2k. 然后做T2想贪心就出来了.十分钟码完T3 ...
- Android 开源库 GitHub 托管
本文微信公众号「AndroidTraveler」首发. 背景 之前给大家写过一篇文章 Android 上传开源项目到 jcenter 实战踩坑之路,分享了上传开源项目到 jcenter 上面的一些踩坑 ...
- 一文学会Go语言
go语言随手记 -- go语言定位于高并发服务端程序 1.基本数据类型 boolstringint int8 int16 int32 int64uint uint8 uint16 uint32 uin ...