对于wait,锁池和等待池的疑问
来源:8-7 notify和notifyall的区别
湿地车手
2021-12-21
老师,这里我有点绕,你能不能帮我看一下我的理解是不是对的。
当一个线程被wait()、wait(long ms)、sleep(long ms),或者自己对其他线程使用join()的时候,都会进入一个等待池中,只不过进入超时等待状态的线程会在时间到之后自动唤醒。
然后无论是自动唤醒的线程还是被notify的线程都会进入到一个锁池中去竞争他们各自需要的锁。假如在锁池中竞争到了锁,或者有些线程根本不需要竞争锁,那么就会进入runnable的就绪状态等待CPU调度。
假如在锁池中没有竞争到锁,那么就会被直接阻塞进入blocked状态。
对于notifyAll来说,相当于清空等待池,将所有线程都赶入锁池中,然后在锁池中再根据每个线程的自身情况分别判断接下来该进入就绪态还是阻塞态。
1.我这样理解有问题么?
2.是不是无论需不需要竞争锁都会先进入锁池去尝试竞争锁,假如不需要就视作竞争成功处理?
3.sleep的底层是不是就是调用的unpark啊?
4.对于等待和阻塞的区别是不是就在于只有碰到synchronized关键字的时候才会进入到阻塞(被动),而在任何情况下都可以通过除wait方法外的其他方式进入等待状态(主动调用),对于wait来说该线程不仅进入等待状态,还会失去当前synchronized( o ) 锁住的 锁o
谢谢老师
1回答
-
同学好,
首先,sleep不会进入等待池,因为本身就没释放锁,只有wait才会进入等待池;
其次,第一次进来发现没有竞争,是不用进锁池的,具体可以看锁膨胀;
再者,sleep底层调用的是操作系统的
ParkEvent
的park
函数,不是LockSupport.park;https://juejin.cn/post/6844903971463626766
最后,阻塞是被动的,等待可以是主动的
052022-07-10
相似问题