为什么我得到 Thread t1 的 IllegalMonitorStateException
Why am I getting IllegalMonitorStateException for the Thread t1
我收到以下代码的错误
First thread about to sleep
thread 1 run
Boolean assignment done.
Woke up and about to invoke 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 IncorrectSynchronization.run(HelloWorld.java:23)
at java.lang.Thread.run(Thread.java:748)
当Thread t1 休眠时,我从另一个线程修改锁为false。
然后它会抛出此 IllegalMonitorStateException。还是同一个对象,为什么修改值会导致IllegalMonitorStateException?
当我从同步块内的另一个线程将锁修改为 false 时,我不再收到该错误。任何人都可以解释幕后发生的事情的原因吗?
public class HelloWorld{
public static void main( String args[] ) throws InterruptedException {
SampleTest.runExample();
}
}
class SampleTest{
Boolean flag = new Boolean(true);
public void example() throws InterruptedException {
Thread t0 = new Thread(new Runnable() {
public void run() {
synchronized (flag) {
try {
while (flag) {
System.out.println("First thread about to sleep");
Thread.sleep(2000);
System.out.println("Woke up and about to invoke wait()");
flag.wait();
System.out.println("wait() called");
}
} catch (InterruptedException ie) {
}
}
}
});
Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("thread 1 run");
flag = false;
}
});
t0.start();
Thread.sleep(200);
t1.start();
t0.join();
t1.join();
}
public static void runExample() throws InterruptedException {
SampleTest test = new SampleTest();
test.example();
}
}
这一行有问题:
flag = false;
这改变了 flag
布尔变量的 reference,从原始的 Boolean
对象(它是由不推荐使用的构造函数创建的,不应该used) 到预先创建的 Boolean.FALSE
实例(由于 autoboxing)。当第一个线程调用 flag.wait()
时,该对象不再与其用于同步的对象相同,因此 IllegalMonitorStateException
.
在这种情况下,最好使用 AtomicBoolean
并在另一个线程中改变它的值:
AtomicBoolean flag = new AtomicBoolean(true);
现在第二个线程可以更新同一个对象的值。它还应该通知正在等待对象的第一个线程(像 wait()
,notify()
也需要在调用它的对象上同步):
Thread t1 = new Thread(new Runnable() {
public void run() {
synchronized(flag) {
System.out.println("thread 1 run");
flag.set(false);
flag.notify();
}
}
});
我收到以下代码的错误
First thread about to sleep
thread 1 run
Boolean assignment done.
Woke up and about to invoke 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 IncorrectSynchronization.run(HelloWorld.java:23)
at java.lang.Thread.run(Thread.java:748)
当Thread t1 休眠时,我从另一个线程修改锁为false。 然后它会抛出此 IllegalMonitorStateException。还是同一个对象,为什么修改值会导致IllegalMonitorStateException?
当我从同步块内的另一个线程将锁修改为 false 时,我不再收到该错误。任何人都可以解释幕后发生的事情的原因吗?
public class HelloWorld{
public static void main( String args[] ) throws InterruptedException {
SampleTest.runExample();
}
}
class SampleTest{
Boolean flag = new Boolean(true);
public void example() throws InterruptedException {
Thread t0 = new Thread(new Runnable() {
public void run() {
synchronized (flag) {
try {
while (flag) {
System.out.println("First thread about to sleep");
Thread.sleep(2000);
System.out.println("Woke up and about to invoke wait()");
flag.wait();
System.out.println("wait() called");
}
} catch (InterruptedException ie) {
}
}
}
});
Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("thread 1 run");
flag = false;
}
});
t0.start();
Thread.sleep(200);
t1.start();
t0.join();
t1.join();
}
public static void runExample() throws InterruptedException {
SampleTest test = new SampleTest();
test.example();
}
}
这一行有问题:
flag = false;
这改变了 flag
布尔变量的 reference,从原始的 Boolean
对象(它是由不推荐使用的构造函数创建的,不应该used) 到预先创建的 Boolean.FALSE
实例(由于 autoboxing)。当第一个线程调用 flag.wait()
时,该对象不再与其用于同步的对象相同,因此 IllegalMonitorStateException
.
在这种情况下,最好使用 AtomicBoolean
并在另一个线程中改变它的值:
AtomicBoolean flag = new AtomicBoolean(true);
现在第二个线程可以更新同一个对象的值。它还应该通知正在等待对象的第一个线程(像 wait()
,notify()
也需要在调用它的对象上同步):
Thread t1 = new Thread(new Runnable() {
public void run() {
synchronized(flag) {
System.out.println("thread 1 run");
flag.set(false);
flag.notify();
}
}
});