一个使用wait与notify的错误案例

public class TestWait {
    public static void main(String[] args) throws InterruptedException {
        Object shareObject = new Object();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (shareObject) {
                    try {
                        System.out.println(Thread.currentThread().getName()+" wait!");
                        shareObject.wait();
                        System.out.println(Thread.currentThread().getName()+" running!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread.start();
        Thread.sleep(2000);
        shareObject.notify();
    }
}

不想通过notify()去幻象阻塞线程,但是确抛出异常:

Thread-0 wait!
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at com.riant.day03.demo01.threadmethod.TestWait$1.run(TestWait.java:18)
	at java.lang.Thread.run(Thread.java:748)
Exception in thread "main" java.lang.IllegalMonitorStateException
	at java.lang.Object.notify(Native Method)
	at com.riant.day03.demo01.threadmethod.TestWait.main(TestWait.java:28)

按道理wait()方法使用后面,会Thread-0,且会释放shareObject的对象监视器锁,但是为什么会抛出IllegalMonitorStateException。
查看java doc关于IllegalMonitorStateException描述

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor
一个线程试图去等待一个一个对象的监视器锁或者通知那些监听这个监视器锁的线程,但是这个线程没有拥有这个对象的监视器锁,

也就是说当前的线程不是此对象监视器的所有者。

才发现在notify方法中没有使用同步代码块,修改之后解决问题:

package com.riant.day03.demo01.threadmethod;

public class TestWait {
    public static void main(String[] args) {
        Object shareObject = new Object();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (shareObject) {
                    try {
                        System.out.println(Thread.currentThread().getName() + " wait!");
                        shareObject.wait();
                        System.out.println(Thread.currentThread().getName() + " running!");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (shareObject) {
            shareObject.notify();
        }
    }
}
上一篇:多线程实现循环


下一篇:C++ get time in milliseconds precision