在运行此操作时,我得到了IllegalMonitorStateException
,因为即使是线程在对象isEven
没有锁定时也会尝试通知。为什么会这样?如果一个线程锁定了对象,它应该只能进入同步块内部。
public class NumPrinter implements Runnable{
public static Boolean isEven = true;
private boolean isEvenThread;
private int i;
public void run() {
while(i < 100){
synchronized(isEven){
boolean notPrinting = (isEven ^ isEvenThread);
System.out.println(notPrinting);
if(notPrinting) {
try {
isEven.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(i + ",");
i = i+2;
isEven = !isEven;
isEven.notifyAll();
}
}
}
public NumPrinter(boolean isEvenThread) {
this.isEvenThread = isEvenThread;
if(isEvenThread)
i = 0;
else
i = 1;
}
}
public class MultiThreading {
public static void main(String[] args) {
Thread oddt = new Thread(new NumPrinter(false), "Odd");
Thread event = new Thread(new NumPrinter(true), "Even");
event.start();
oddt.start();
}
}
答案 0 :(得分:2)
您可能需要在常量对象上同步/等待/通知。同时将isEven
声明为volatile。最后,将wait()
调用放在循环中,将循环条件检查为官方文档recommends:
public class NumPrinter implements Runnable {
private static final Object monitor = new Object();
private static volatile boolean isEven = true;
private final boolean isEvenThread;
private int i;
@Override
public void run() {
while (i < 100) {
synchronized (monitor) {
while (isEven ^ isEvenThread) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.print(i + ",");
i = i + 2;
isEven = !isEven;
monitor.notifyAll();
}
}
}
...
}
答案 1 :(得分:1)
我不是Java专家,但你在这里重写了同步令牌:
isEven =!isEven;
这可能不是你唯一的问题,但至少要使用另一个同步令牌(不会被重写)。