天天看点

多线程的IllegalMonitorStateException异常分析

今天看了一篇线程通信的帖子。想着研究一下线程之间的通信,使用的是object方法的wait和notify进行实现。代码如下:

public static void demo2() {
        final Thread A = new Thread(new Runnable() {
            @Override
            public void run() {
                    System.out.println("A1");
                    try {
                        //调用wait,notify,notifyAll时,必须要拥有该对象的锁
                        //如果没有拥有该对象的锁却调用该对象的wait,notify,notifyAll方法
                        //就会报出IllegalMonitorStateException异常
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("A2");
                    System.out.println("A3");
                }
        });
        Thread B = new Thread(new Runnable() {
            @Override
            public void run() {
                    System.out.println("B1");
                    System.out.println("B2");
                    System.out.println("B3");
                    lock.notify();
                }
        });
        A.start();
        B.start();
    }
           

编译不报错,但是运行程序时报错,报错如下:

Exception in thread "Thread-0" A1
B1
B2
B3
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at cn.org.bjca.ThreadCommunicate$3.run(ThreadCommunicate.java:57)
	at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalMonitorStateException
	at java.lang.Object.notify(Native Method)
	at cn.org.bjca.ThreadCommunicate$4.run(ThreadCommunicate.java:71)
	at java.lang.Thread.run(Thread.java:745)

Process finished with exit code 0
           

在网上搜索了一下,知道了原因,特在此记录一下。

调用wait,notify,notifyAll时,必须要拥有该对象的锁,

如果没有拥有该对象的锁却调用该对象的wait,notify,notifyAll方法

就会报出IllegalMonitorStateException异常

获取一个对象锁的最简单方式是使用synchronized关键字。

代码修改如下:

public static void demo2() {
        final Object lock = new Object();
        final Thread A = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    System.out.println("A1");
                    try {
                        //调用wait,notify,notifyAll时,必须要拥有该对象的锁
                        //如果没有拥有该对象的锁却调用该对象的wait,notify,notifyAll方法
                        //就会报出IllegalMonitorStateException异常
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("A2");
                    System.out.println("A3");
                }
            }
        });
        Thread B = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    System.out.println("B1");
                    System.out.println("B2");
                    System.out.println("B3");
                    lock.notify();
                }
            }
        });
        A.start();
        B.start();
    }
           

OK,问题解决,程序可以正常执行。

继续阅读