我收到以下代码的非法状态例外:
synchronized (this) {
try {
Thread.currentThread().wait();
notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
我可以做的是同步“this”将捕获Monitor on Object调用方法,因为我在当前线程对象上调用wait而我真的没有锁定我得到错误。请验证我的理论。
答案 0 :(得分:0)
你在当前线程上调用wait,在此调用它。
this.wait();
但是你永远不会得到notifyAll
,因为没有线程进入同步块
可以达到notofyAll
方法。他们都会先等待它。
我想你想让一个Thread等待另一个Thread做一些工作。
以下是线程之间同步如何工作的简短示例
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
Object monitor = new Object();
Thread t1 = new Thread(new R1(monitor));
Thread t2 = new Thread(new R2(monitor));
t1.start();
t2.start();
t2.join();
t1.join();
}
public static class R1 implements Runnable {
private Object monitor;
public R1(Object monitor) {
this.monitor = monitor;
}
public void run() {
System.out.println("R1 entered run");
synchronized (monitor) {
try {
monitor.wait();
System.out.println("R1 got monitor back");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static class R2 implements Runnable {
private Object monitor;
public R2(Object monitor) {
this.monitor = monitor;
}
public void run() {
System.out.println("R2 entered run");
synchronized (monitor) {
System.out.println("R2 will sleep for 1 sec");
try {
Thread.sleep(1000);
System.out
.println("R2 will notify all threads waiting for monitor");
monitor.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
输出是:
R1 entered run
R2 entered run
R2 will sleep for 1 sec
R2 will notify all threads waiting for monitor
R1 got monitor back
答案 1 :(得分:0)
你已经获得了
的锁定这个(当前对象)
你打电话给`
等待()
`当前线程就是为什么。
你应该在调用wait之前获取锁定,通知notifyAll
答案 2 :(得分:0)
案例1
...
synchronized(this){
this.wait();
}
...
情况2
...
synchronized(this){
Thread.currentThread.wait();
}
...
案例1是明智的代码。它等待另一个线程在“notify[All]()
”对象上调用this
。
案例2看起来很傻。它只能在当前线程和“this
”是同一个对象时执行,或者您已经锁定了当前线程。否则,你会得到IllegalMonitorStateException
。在Thread对象上进行同步是一件坏事,因为你无法确定还有什么可能在它们上同步。
顺便说一句,如果你想要做的只是在程序中暂停一段时间,你应该sleep()
,而不是wait()
。
答案 3 :(得分:0)
来自Java doc for Object class wait()方法:
IllegalMonitorStateException - 如果当前线程不是所有者 对象的监视器。
在您的代码中,当前主题是this
监视器的所有者,wait
上调用了Thread.currentThread
。
将Thread.currentThread().wait();
替换为this.wait();