理解IllegalMonitorStateException异常的抛出原因

转自:http://macleo.iteye.com/blog/625873  作者:macleo  感谢,如果侵权,请联系删除之。

 

在学习中有时会出现wait()方法抛 IllegalMonitorStateException 的情况,查阅wait 方法的API时,对于 IllegalMonitorStateException 的说明如下:

 

IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。

 

从网上找来一段,自己改了改想了想,不敢说绝对正确,但确是自己的心得和理解(若有不正确的地方,恳请各位大侠指正吧...)

以下代码抛IllegalMonitorStateException

 

 1 class M018   
 2 {  
 3     public static void main(String[] args) throws Exception  
 4     {  
 5         M018 m18 = new M018();  
 6         m18.one();  
 7     }  
 8   
 9     public void one() throws Exception  
10     {  
11         Object obj = new Object();  
12         synchronized (Thread.currentThread())  
13         {  
14             obj.wait();//当前线程是主线程(所有者是Object)  
15             //obj.notify();  
16         }  
17     }  
18 }  
19   
20   
21 /** 
22  *2010-3-26 下午23:30:59 
23  *Conclusion:  
24  IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。  
25  */ 

 

上例中,synchronized的对象是Thread.currentThread(),查阅currentThread()的说明如下:

 

static Thread currentThread()
          返回对当前正在执行的线程对象的引用。

 

因为,Thread.currentThread()返回的当前线程的引用与当前线程,指向的是不同对象.

请看如下代码:

 1     import static java.lang.System.out;  
 2     class M019   
 3     {  
 4         public static void main(String[] args)   
 5         {  
 6             One o = new One();  
 7             Thread o1 = new Thread(o);  
 8             Thread o2 = o.getThread();  
 9             //o1.start();//将此行注释去除,执行正常  
10             //o2.start();//将此行注释去除,抛IllegalMonitorStateException   
11             if(o1==o2)  
12                 out.println("equals");  
13             else  
14                 out.println("Not equals");  
15             if(o1.equals(o2))  
16                 out.println("equals");  
17             else  
18                 out.println("Not equals");  
19         }  
20     }  
21       
22     class One implements Runnable  
23     {  
24         public void run()  
25         {  
26             for(int i = 0; i < 10 ; i++)  
27             {  
28                 out.print(i+" ");  
29             }  
30         }  
31       
32         public Thread getThread()  
33         {  
34             return Thread.currentThread();  
35         }  
36     }  
37       
38     /** 
39      *2010-3-26 下午23:58:59 
40      *Conclusion:  
41      */  

1.比较引用与equals方法都将返回Not equals
2.在上例中,之所以没有重写equals方法的原因是,Object对equals方法的定义如下:

 

    public boolean equals(Object obj) {  
    urn (this == obj);  

 所以没有必要重写.


以下代码进入wait状态,退出时按Ctrl+c,但是不抛IllegalMonitorStateException异常.

 

import static java.lang.System.out;  
class M018   
{  
    public static void main(String[] args) throws Exception  
    {  
        M018 m18 = new M018();  
            m18.one(m18);  
            //System.out.println("Hello World!");  
    }  
  
    public void one(M018 n) throws Exception  
    {  
        Object obj = new Object();  
        synchronized (this)  
        {  
            n.wait();  
        }  
    }  
}  
  
  
/** 
 *2010-3-26 下午23:30:59 
 *Conclusion:  
 IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。  
 */  

 

总结如下:
非当前线程的引用调用wait方法,抛IllegalMonitorStateException异常

posted on 2012-04-28 10:27  按图索骥  阅读(233)  评论(0)    收藏  举报

导航