Java多线程 wait notify notifyAll的特点 性质&&wait 的原理&& 线程状态转换的特殊情况

wait notify notifyAll的特点 性质

  1. 执行wait notify notifyAll 之前, 必须首先获取到 monitor 否则抛出异常
  2. notify 只能唤醒其中一个线程. 至于是哪一个,也由JVM决定.
  3. 这三个方法,都是属于Object类的. 因此任何对象都可以调用这三个方法. 并且这个三个方法在Object类中, 都是用final修饰的, 代表子类无法重写这三个方法.
  4. Jdk有封装好的有类似功能的Condition接口
  5. 如果同时持有多个锁, 那么wait方法释放的锁, 只会释放调用wait对象的那把锁. 释放锁的顺序, 获取锁的顺序, 非常的重要, 否则可能会出现死锁.

wait 的原理

wait的原理, 如下图. 主要有两个概念

  1. 入口集 Entry Set : 为下图的左上角的部分
  2. 等待集 Wait Set : 为下图的左中间和左下的部分.

从数字1开始, 进入 Entry Set , 而Entry Set 中绿色的圆圈, 代表每一个线程去争夺资源.
而右侧部分(the owner )的紫色圆圈, 代表此线程已经获得了锁资源.
而紫色的线程, 释放锁有两种情况.
a. 正常执行完了run方法中的代码, 释放了锁
b. 在执行线程逻辑的过程中, 执行了wait方法, 那么就会进入数字3 的情况, 释放了锁, 进入了下图中, 左边中间部分的wait等待集中, 变成了蓝色的线程.

直到该等待的线程, 被其他线程notify或者notifyAll 唤醒了, 那么就会进入到左下的set集合中.

set集合与wait集合的区别在于. wait集合中, 由于一直处于阻塞的状态,没有被唤醒, 还没有获取锁的意愿, 而在set集合中, 由于被唤醒了, 因此有获得锁的意愿了, 可以再次的去抢夺锁的资源.
因此下图中的数字5 和 2 的acquire 的含义是一样的, 都是去获取锁, 重新进入图中右侧的紫色部分.

线程状态转换的特殊情况

如下的红色的箭头, 为线程转换的特殊状态.
即waiting状态的时候, 可能会直接进入Blocked状态.
waiting和timed_waiting状态, 也可能直接进入terminated终止的状态.

  • Obeject.wait()状态刚被唤醒的时候, 即上面wait的原理图中, 由 蓝色变为红色的时候, 通常不能立即抢到 monitor锁, 那么就会从waiting状态, 直接进入Blocked状态,抢到锁之后, 再转换到Runnable状态.
    对于jdk官方文档中, 也有提及进入Blocked状态的两种情况.
  • 线程在执行的过程中, 如果发生了异常, 那么可以直接跳转到终止的Terminated状态, 即直接从waiting或timed_waiting 到terminated . 这也是一个特殊的状态转换情况.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值