我试图让两个线程相互打印出来,但我得到的结果是:
0
Exception in thread "Thread-0" wait in decrement
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at thread.Multithread2.increment(Multithread2.java:38)
at thread.Multithread2.run(Multithread2.java:18)
at java.lang.Thread.run(Unknown Source)
我已经在synchronized块中包含了共享对象,并在此对象上调用了wait()/ notify()。我不知道为什么它仍然会抛出异常。
public class Multithread2 implements Runnable {
private Integer integer;
private int method;
public Multithread2(Integer integer, int method) {
this.integer = integer;
this.method = method;
}
@Override
public void run() {
try {
Thread.sleep(20);
for(int i = 0; i < 5; i++) {
if(method == 1) {
increment();
} else {
decrement();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void increment() throws InterruptedException {
synchronized(integer) {
while(integer > 0) {
integer.wait();
}
System.out.println(integer);
integer++;
integer.notify();
}
}
public void decrement() throws InterruptedException {
synchronized(integer) {
while(integer <= 0) {
integer.wait();
}
System.out.println("decrement: " + integer);
integer--;
integer.notify();
}
}
}
主要方法:
Integer integer = new Integer(0);
Thread t1 = new Thread(new Multithread2(integer, 1));
t1.start();
Thread t2 = new Thread(new Multithread2(integer, 2));
t2.start();
答案 0 :(得分:2)
integer++
相当于
integer = Integer.valueOf(integer.getValue() + 1);
因此它使用不同的Integer实例初始化整数变量。整数是不可变的,因此它的状态不能改变。因为你在这个新的Integer实例上调用notify(),并且你没有获得这个新实例的锁定,所以你得到了那个例外。
使用您自己的,可变的,线程安全的Counter类。在共享的,不可变的Integer实例上进行同步是一个糟糕的主意。顺便说一句,一个好的经验法则是制作同步final
的字段。这样做会导致编译错误,在这种情况下编译错误是你的朋友,只要你注意实际上对你说的是什么。