проблема здесь:
synchronized(p1)
{
p2.cont = true;
p2.notify();
}
Вы делаете p2.notify()
, когда у вас нет блокировки на p2
(вы должны держать монитор, чтобы вызвать уведомление об этом). Измените synchronized(p1)
на synchronized(p2)
. Кроме того, вам нужно отменить другое синхронизированное предложение, что также является ошибочным. Итак, в качестве примера:
synchronized(p1)
{
p1.cont = false;
// p1.notify(); <- do you need this here?
}
table.removeAll();
synchronized(p2)
{
p2.cont = true;
p2.notify();
}
Кроме того, ваш другой код тоже немного неправильный, очень плохая практика - блокировать весь цикл, сделать его немного более атомарным.
while (!cont) {
synchronized (this) {
try {
wait();
} catch (Exception e) {
}
}
}
Дополнительная оптимизация, по возможности избегайте synchronised
:
if (p1.cont) {
synchronized(p1)
{
p1.cont = false;
// p1.notify(); <- do you need this here?
}
}
table.removeAll();
if (!p2.cont) {
synchronized(p2)
{
p2.cont = true;
p2.notify();
}
}
Сделайте здесь поле cont volatile
и отразите для другой части оператора if подходящее значение.
Редактировать: оглядываясь на это и борясь с ошибкой параллелизма, с которой я недавно столкнулся, любой, кто реализует этот шаблон, может столкнуться с проблемой бесконечного ожидания, если условный объект, на который был заблокирован и частично заблокирован, просматривается условным условием. цикла while (это потому, что существует разрыв, в котором состояние может меняться между вычислением условия и наложением оператора ожидания). В этом случае поместите синхронизированный блок на вне цикла.