Java Thread: obj.wait(), obj.notify(), obj.notifyAll()

JVM规范 2nd,  CHAPTER 8 Threads and Locks, 8.14 Wait Sets and Notification  读书笔记

假设我们拥有 线程T 以及 对象obj

Object obj = Object();
1. obj拥有一个monitor

2. obj还拥有一个wait set(里面存储的是线程满足下面条件:

a. 不拥有 obj 的锁;

b. 都阻塞着,不能被schedule;

c. obj.notify()使得 此set中 其中一个线程schedule-enabled,然后此线程 去夺 ob j的 lock;

d. obj.notifyAll()使得 此set中 所有线程都schedule-enabled,然后所有线程 都去夺 obj 的 lock,得到的可以破除阻塞,得不到的再次进入 obj wait set;


线程T 调用 obj.wait(), obj.notify(), obj.notifyAll() 的前提:线程 T 已经获得了 obj 的 lock

线程获得 obj 的锁(synchronized), 绝对不会将将自己(T)加入到 obj 的 wait set 中去


假设 T 获得了 obj 的锁,并且 T 在 obj 的 lock 上加了 N 次锁,则当T 执行 obj.wait() 时
1. 将 T 被 加进 obj 的 wait set 中
2. 使得 T 不能被schedule(the wait() method disables T for thread scheduling purposes)
3. 执行 N 次 unlock 操作,从而 T 释放 obj 的锁(注意:T得到的其他 obj1, obj2...的锁是不会被释放的)
4. T 开始睡眠

5. 三件事情中的任何一件发生后,T 就会醒来

a. T'调用 obj.notify(),而 T 正好被 调度器 选为 被 notified的那个线程

b. T'调用了 obj.notifyAll()
c. T 执行的是 obj.wait(timeoutMillscnds); 过了 timeoutMillscnds 毫秒
6. obj 的 wait set 将 T 从里面 剔除,从而, T 恢复为 “可以被调度”(也就是说,T 醒过来啦)
7. T 再去 获得 obj 的lock(当然,T 可能获得不到,因为 T 需要和其他线程竞争此锁)

8. T 得到 obj 的 lock 后,再执行 N-1 次的 lock,然后,wait() 调用结束(也就是说,此时 T 在 obj 的 lock 上,加了  N 次锁,一如 obj.wait() 调用之前)

就是说:当从 wait() 返回后,lock 状态 exactly the same 和 wait() 调用前


T 执行 obj.notify()的前提是 T 拥有 obj 的锁,否则就会抛出 IllegalMonitorStateException

如果 obj wait set 不空,就会从 obj wait set 中随机(注意是随机)选中一个线程,然后,被选中的这个线程 就被从 wait set 中移除,然后,此线程就可以 再次 被调度(注意:非常重要的一点,在 被选中线程 被移除后,此 被选中线程 还是不能立即执行指令流,必须要等到 T 释放掉 obj 的锁后(在 obj 上加的那些次lock,必须都去掉),被选中的线程才能够抢到锁,然后执行指令流)


T 执行 obj.notifyAll()的前提是 T 拥有 obj 的锁,否则就会抛出 IllegalMonitorStateException
obj wait set 中的 所有线程都会被从 set 中移除掉,然后,所有这些线程 可以被 schedule(注意:非常重要的一点,在 所有这些线程 被移除后,所有这些线程 都还是不能立即执行指令流的,必须要等到 T 释放掉 obj 的锁后(在 obj 上加的那些次lock,必须都去掉),所有这些线程 中的 某一个才能够抢到锁,然后执行指令流。当然,没抢到锁的,再次进入到 obj wait set 中)。这里 所有线程 都可以被schedule,当然,就像上面括号的内容那样,这些线程还要在 T 释放lock后,再去竞争 obj 的lock,然后获得lock者才可以运行


问题总是有的,下面这些还是不知道怎么回事

里面总是出现:
1. The wait() method disables the current thread for thread scheduling purposes
2. The thread T is then removed from the wait() set, and reenabled for thread scheduling
我想知道:到底是谁在 schedule 我们的线程。JVM中的哪个部分,而JVM中的这个部分又是怎样被 OS 所控制的
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值