java多线程——监视锁(monitor)(转)

https://blog.csdn.net/hqq2023623/article/details/51000153

java中每个对象都有唯一的一个monitor,想拥有一个对象的monitor的话有以下三种方式:

1.执行该对象的同步方法

  1. public synchronize a () {}  

2.执行该对象的同步块

  1. synchronize(obj) {  
  2. }  

3.执行某个类的静态同步方法

  1. public static synchronize b(){}  


tips:拥有monitor的是线程

1.同时只能有一个线程可以获取某个对象的monitor

2.一个线程通过调用某个对象的wait()方法释放该对象的monitor并进入休眠状态,

直到其他线程获取了被该线程释放的monitor并调用该对象的notify()或者notifyAll()后再次竞争获取该对象的monitor

3.只有拥有该对象monitor的线程才可以调用该对象的notify()和notifyAll()方法

如果没有该对象monitor的线程调用了该对象的notify()或者notifyAll()方法将会抛出java.lang.IllegalMonitorStateException

 

测试代码:

 

  1. public class TestNotify implements Runnable {  
  2.   
  3.     private final Object obj = new Object();  
  4.   
  5.     @Override  
  6.     public void run() {  
  7.         synchronized (obj) {  
  8.             notify();  
  9.             //obj.notify();  
  10.         }  
  11.     }  
  12.   
  13.     public static void main(String[] args) {  
  14.         //ShareVars shareVars = new ShareVars();  
  15.         new Thread(new TestNotify ()).start();  
  16.     }  
  17.   
  18. }  

当调用notify()时会抛出异常

状态分析:

1.可以看到,此时线程执行的同步块为synchronized(obj),即只获得了obj的monitir

2.notify()是调用TestNotify的方法,当前线程并未达到拥有TestNotify对象monitor的三个条件之一

3.所以抛出java.lang.IllegalMonitorStateException

 

wait()方法也和notify()一样有相同的限制:

  1. @Override  
  2.  public void run() {  
  3.      synchronized (obj) {  
  4.          try {  
  5.              wait();  
  6.          } catch (InterruptedException e) {  
  7.              e.printStackTrace();  
  8.          }  
  9.      }  
  10.  }  

修改run方法为上述代码也会抛出java.lang.IllegalMonitorStateException

posted on 2018-04-09 15:42  devilwind  阅读(474)  评论(0编辑  收藏  举报