java对象的Minitor属性解析 及多线程下的wait()notify()使用实例

参考博文
https://blog.csdn.net/lmb55/article/details/79349680

java线程运行流程图.png
最近在看java基础,随学随记吧。
前提概念引入 :

Java对象的Monitor机制

Java虚拟机(JVM)给每个对象和class字节码都设置了一个监视器叫Monitor(只有一个),Monitor就是为了防止多线程并发代码的重入,同时在Object类中还提供了notify和wait方法来对线程进行控制。下面这个图描述了线程和Monitor之间的关系,以及线程的状态转换图:


java monitor.png

图中三块区域的解释如下

1、入口队列区(Entry Set):表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则进入拥有者(就是获取了对象的monitor);否则一直等待别的线程释放对象锁,直到对象锁被其他线程释放,进入区(Entry Set)的所有线程立即参与竞争。
2、拥有Monitor者(The Owner):表示某一线程成功竞争到对象锁。
3、等待队列区(Wait Set):表示线程通过对象的wait方法释放对象的锁,并在等待区等待被唤醒。

下面要说的是Monitor的机制

之前说了Monito的机制是为了在多线程下同步访问而设计的(也就是同一时刻只能有一个线程持有该对象的Monitor)

我们可以把他抽象成一个房间,这房间同一时刻只有一个线程进入。
入口队列区(Entry Set)中的线程竞争(由cpu调度)决定哪一个线程可以进入房间,当有一个线程进入房间,(Entry Set)队列中的其他线程继续等待,进入房间即为持有Monitor就可以去执行受保护的代码段,执行完毕后释放Monitor。

再说一下wait-set队列。当一个线程拥有Monitor后,经过某些条件的判断(比如用户取钱发现账户没钱),这个时候需要调用Object的wait方法,线程就释放了Monitor,进入wait-set队列,等待Object的notify方法(比如用户向账户里面存钱)。当该对象调用了此对象的notify方法或者notifyAll方法后,wait-set中的线程就会被唤醒,然后在wait-set队列中被唤醒的线程和entry-set队列中的线程一起通过CPU调度来竞争对象的Monitor(需要注意的是:
当一个线程在wait-set中被唤醒后,并不一定会立刻获取Monitor,它需要和其他被唤醒的线程加上入口队列区(Entry Set)中的线程一起竞争Monitor
),最终只有一个线程能获取对象的Monitor。
//后续讲解

你可能感兴趣的:(java对象的Minitor属性解析 及多线程下的wait()notify()使用实例)