IllegalMonitorStateException 异常例子的解决方法
IllegalMonitorStateException
IllegalMonitorStateException异常发生是由于程序员没有注意notify(),notify(),wait()方法的使用条件,没有真正理解线程同步机制。如果当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。
下例:
生产者线程
public class Producer extends Thread{ private Share shared; private int number; public Producer(Share s,int number){ shared=s; this.number=number; } public void run(){ for(int i=0;i<10;i++){ shared.put(i); System.out.println("生产者"+this.number+" 输出的数据为:"+i); try{ sleep((int)(Math.random()*100)); }catch(InterruptedException e){} } } }
共享资源对象
public class Share{ private int contents; private boolean available=false; public int get(){ while(available==false){ try{ wait(); }catch(InterruptedException e){} } available=false; notifyAll(); return contents; } public void put(int value){ while(available==true){ try{ wait(); }catch(InterruptedException e){} } available=true; notifyAll(); contents=value; } }
消费者程序
public class Consumer extends Thread{ private Share shared; private int number; public Consumer(Share s,int number){ shared=s; this.number=number; } public void run(){ int value=0; for(int i=0;i<10;i++){ value=shared.get(); System.out.println("消费者"+this.number+" 得到的数据为:"+value); } } }
主程序
public class PCTest{ public static void main (String[] args) { Share s=new Share(); Producer p=new Producer(s,1); Consumer c=new Consumer(s,1); p.start(); c.start(); } }
运行结果:
E:/Java>java PCTest 生产者1 输出的数据为:0 消费者1 得到的数据为:0 Exception in thread "Thread-1" java.lang.IllegalMonitorStateException: current t hread not owner at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Unknown Source) at Share.get(Share.java:8) at Consumer.run(Consumer.java:13) 生产者1 输出的数据为:1 Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current t hread not owner at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Unknown Source) at Share.put(Share.java:18) at Producer.run(Producer.java:12)
原因在于Share类中调用share对象的wait()方法时,不在同步方法或同步代码块中,因而当前线程并没有Share对象的锁,不能调用wait()方法。
应改为:
public class Share{ private int contents; private boolean available=false; public synchronized int get(){ while(available==false){ try{ wait(); }catch(InterruptedException e){} } available=false; notifyAll(); return contents; } public synchronized void put(int value){ while(available==true){ try{ wait(); }catch(InterruptedException e){} } available=true; notifyAll(); contents=value; } }
