Почему несколько потоков могут получить доступ к синхронизированному блоку?
Во время этого я получаю 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();
}
}
2 ответа
Вероятно, вам нужно вместо этого синхронизировать / ждать / уведомлять постоянный объект. Также объявите isEven
как изменчивый. Наконец, положить wait()
вызов в цикле, проверяющий состояние цикла, поскольку официальная документация рекомендует:
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();
}
}
}
...
}
Я не специалист по Java, но вы переписываете токен синхронизации здесь:
isEven =! isEven;
Это может быть не единственной вашей проблемой, но, по крайней мере, использовать другой токен синхронизации (который не будет переписан).