概述
java虚拟机给每个对象和class字节码都设置了一个监视器对象Monitor,用于检测并发代码的重入。
Monitor机制
分析:Monitor 可以类比为一个特殊的房间,这个房间有一些被保护的数据,Monitor保证每次只能有一个线程能进入这个房间进行访问被保护的数据,进入房间即为持有Monitor,退出房间即为释放Monitor。
当一个线程需要访问受保护的数据(即需要获取对象的Monitor)时,它会首先在entry-set入口队列排队(这里不是真正的按照排队顺序),如果没有其它线程正在持有对象的Monitor,那么它会和entry-set和wait-set队列的被唤醒的线程进行竞争(即通过CPU调度),选出一个线程获取对象的Monitor,执行受保护的代码段,执行完释放Monitor,如果已经有线程持有对象的Monitor,那么需要等待释放Monitor后再进行竞争。
wait-set队列,当一个线程拥有Monitor后,经过某些条件的判断,这个时候需要调用Object的wait方法,线程就释放了Monitor,进入wait-set队列,等待Object的notify方法。当该对象调用notify或notifyAll方法后,wait-set中的线程就会被唤醒,然后在wait-set队列中被唤醒的线程和entry-set队列中的线程一起通过CPU调度来竞争对象的Monitor,最终只有一个线程能获取对象的Monitor。