关于IllegalMonitorStateException异常的解释之一

注意

  在同步控制方法或同步控制块里调用wait(),notify()和notifyAll()。如果在非同步控制方法里调用这些方法,程序能通过编译,但运行的时候,将得到IllegalMonitorStateException异常,并伴随着一些含糊的消息,比如"当前线程不是拥有者"。消息的意思是,调用wait(),notify()和notifyAll()的线程在调用这些方法前必须"拥有"对象的锁。当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常。

package pro_cus;


/**
* 生产者
*/
public class Productor extends Thread{
    
    private Clerk clerk;
    private int times=0;
    public Productor(Clerk clerk) {
        this.clerk = clerk;
    }
    public void run() {
        
        synchronized(clerk) {
            while(times < 11) {
                if(clerk.pros == 5) {
                    try {
                        clerk.wait(); // 不能使用 wait  如果不用clerk. 则wait方法的调用者是Productor,不是当前线程的锁对象,
                        // 当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常
} catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } clerk.pros++; clerk.notify(); //不能使用notify 不能使用 notify 如果不用clerk. 则notify方法的调用者是Productor,不是当前线程的锁对象,
                        // 当前的线程不是此对象锁的所有者,却调用该对象的notify(),notify(),wait()方法时抛出该异常
System.out.println("生产["+clerk.pros+"]号产品"); System.out.println("生产第["+(times+1)+"]次"); times++; } } } } package pro_cus; /** * 消费者 * @author Gary * @time 2019年8月22日 */ public class Cus extends Thread{ private Clerk clerk; private int times=0; public Cus(Clerk clerk) { this.clerk = clerk; } public void run() { synchronized(clerk) { while(times<11) { if(clerk.pros==0) { try { clerk.wait(); //不能使用wait 同理 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } clerk.pros--; clerk.notifyAll(); //不能使用 notifyAll 同理 times++; System.out.println("消费["+clerk.pros+"]号产品"); System.out.println("第["+times+"]次消费"); } } } } ------测试 package pro_cus; public class Clerk { public int pros=0; public static void main(String[] args) { Clerk clerk = new Clerk(); Productor pro = new Productor(clerk); Cus cus = new Cus(clerk); pro.start(); cus.start(); } }

猜你喜欢

转载自www.cnblogs.com/Gary757/p/11395110.html