monitor中entry set和wait set协作解析
大家好,我是欧阳方超,微信公众号同名。
1 monitor概念
1.1 定义与作用
在Java中,monitor是一种同步机制,用于控制多个线程对共享资源的访问。它就像是一个保护罩,确保在同一时刻只有一个线程能够访问被保护的代码块。当一个线程进入被保护的代码块时,它会获取monitor的锁,其他线程如果也想进入这个代码块,就必须等待这个锁被释放。
1.2 内部结构关联
monitor和对象在Java内存模型中有紧密的联系。每个Java对象都有一个monitor与之关联,从字节码层面看,当使用synchronized关键字修饰方法或代码块时,JVM会为对应的对象关联一个monitor。
2 entry set
2.1 定义与作用
entry set是monitor内部的一个集合,用于存放那些尝试获取monitor锁但尚未成功的线程。这些线程处于阻塞状态(blocked),等待锁被当前持有释放。
2.2 工作流程
当一个线程执行到被synchronized修饰的代码块或方法时,如果锁已经被其他线程持有,这个线程就会被放入entry set。例如,有T1、T2、T3三个线程都尝试访问同一个被synchronized保护的方法。如果T1先获取了锁,那么T2和T3就会被放入entry set。当T1执行完方法释放锁后,JVM会从entry set中选择一个线程来获取锁并执行方法。
2.3 与monitor关系
entry set是monitor的一部分,它是monitor控制线程访问顺序的关键组件之一。monitor通过管理entry set,确保只有一个线程在合适的时候获取锁并访问共享资源。
3 wait set
3.1 定义与作用
wait set也是monitor内部的一个集合,主要用于存放那些调用了对象的wait()方法的线程。当一个线程代用wait()方法时,它会释放当前持有的monitor锁,并进去wait set等待,直到其他线程调用该对象的notify()或者notifyAll()方法。这种机制常用于线程间的协作,例如生产者-消费者模式中,消费者线程在队列为空时可以带调用wait()方法等待,生产者线程生产了新的内容后调用notify()或者notifyAll()方法通知等待的消费者线程。
3.2 工作流程
假设在一个多线程程序中,有一个共享的对列Queue对象,消费者线程在获取到Queue对象的锁后,发现队列为空。此时消费者线程可以调用Queue对象的wait()方法,这会导致它释放Queue对象的锁并进入Queue对应的wait set。当生产者线程向队列中添加元素后,它可以调用Queue对象的notify()或者notifyAll()方法。JVM会从Queue对象的wait set中唤醒一个或所有等待的线程,这些被唤醒的线程会重新尝试获取Queue对象的锁,获取成功后可以从队列中获取元素进行消费。
3.3 与monitor的关系
wait set也是monitor的重要组成部分。它和entry set不同,entry set中的线程是等待获取锁的线程,而wait set中的线程是已经获取过锁,然后主动释放锁并等待特定条件满足后再次获取锁的线程。monitor通过协调wait set和entry set中的线程,实现了复杂的线程同步和协作机制。
4 三者关系图
+--------------------------- Monitor ---------------------------+
| |
| Entry Set Owner Wait Set |
| +---------+ +------+ +---------+ |
| | Thread2 | |Thread1| | Thread4 | |
| | Thread3 | | | | Thread5 | |
| +---------+ +------+ +---------+ |
| |
+------------------------------------------------------------+
4.1 整体流程如下:
a) Entry Set:
当线程请求执行synchronized代码时,首先进入Entry Set;
如果monitor没有所有者,某个线程会获得锁并成为owner;
其他线程在Entry Set中等待;
b) Monitor Owner:
同一时刻只能有一个线程成为monitor的owner;
owner线程可以重复进入同步代码块(可重入性);
c) Wait Set(等待池):
当owner线程调用wait()时,进入Wait Set;
释放monitor所有权;
等待其他线程调用notify()/notifyAll();
线程在进入entry set、成为owner、进入wait set时所涉及到的状态转换如下:
-
进入Entry Set:
RUNNABLE -> BLOCKED -
获得锁成为Owner:
BLOCKED -> RUNNABLE -
进入Wait Set:
RUNNABLE -> WAITING -
被唤醒重新进入Entry Set:
WAITING -> BLOCKED
5 总结
本文介绍了 Java 中的 monitor 概念,包括其定义、与对象关联等。还阐述了 entry set、wait set 的作用、工作流程及与 monitor 的关系,最后给出三者关系图及线程状态转换情况,整体呈现了 Java 线程同步协作机制。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。