一个监控器就比如一个建筑,里面有一个特别的房间(building),这个特别的房间(special room)一次只能有一个客户(或者说线程)进去,这个房间有一些资源(数据和代码)。若是一个客户想占用这个特殊的房间,他必须先在门厅等候。安排人员可会按照一些方式给这些客户排个序,好比先进先出安排客户一个一个的进去。可能由于某些缘由一个客户被中止进入特殊房间(也许他以前已经进入了这个特殊的房间),那么他就须要在等候室(wait room)等候,以后再安排他进入特殊的房间。也就是说监控器的做用就是监控进程对特殊房间的访问,它要保证一次只有一个进程能访问这个特殊房间的数据和代码。 java
在java虚拟机中,每个对象和类都与一个监控器逻辑关联。为了实现监控器的互斥能力(一次只能有一个线程访问),每个对象和类都关联一把互斥锁。若是一个线程获取了某个资源的锁,那么其余的线程就都不能得到这个资源的锁了,直到当前线程释放了这个资源的锁其余线程才能获取这个资源的锁并访问这个资源。锁的释放和获取将由java虚拟机自动完成,因此咱们不用关心太多。
java用synchronized关键字来申明监控区,监控区中的代码和数据受监控器监控以保证一次只能有一个线程能访问监控区的资源。 ui
每一个对象和类都与一个监控器相关联,也就是说每一个对象都有一个监控器,而且有本身的临界监控区,这也意味着每一个对象都有能力监控线程序列。当线程执行synchronized 声明的方法或代码块的时候就进入了监控区。
为了使不一样的线程能相互合做,java提供了wait()和notify()来暂停一个线程的执行,以唤醒另外一个等待在这个对象上的线程。
然而这些方法只有在synchronized 声明的代码块和方法中使用才有意义,由于若是一个方法并不须要互斥操做,那么就没有必要为这个方法设置监控区以致于一次只能有一个线程能访问。这样也就不存在等待和唤醒的概念。 spa
参考文章:http://www.programcreek.com/2011/12/monitors-java-synchronization-mechanism/ 线程