今天看了一篇线程通信的帖子。想着研究一下线程之间的通信,使用的是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,问题解决,程序可以正常执行。