Вы отметили правильно, что notifyAll
должен быть назван от синхронизируемого блока.
Однако в Вашем случае, из-за автоупаковки, объект, на котором Вы синхронизировались, не является тем же экземпляром, на который Вы вызвали notifyAll
. На самом деле, новое, увеличенное foo
, экземпляр все еще ограничен стеком, и никакие другие потоки не могли возможно быть заблокированы на wait
вызов.
Вы могли реализовать свой собственный, изменяемый счетчик, на котором выполняется синхронизация. В зависимости от Вашего приложения Вы могли бы также найти, что AtomicInteger удовлетворяет Ваши потребности.
Необходимо также быть подозрительной блокировкой или уведомлением относительно объектов как Строка и Целое число, которое может быть интернировано JVM (для предотвращения создания большого количества объектов, которые представляют целое число 1 или строка"").
Поскольку erickson отметил, код без постинкрементных работ оператора без ошибки:
static Integer foo = new Integer(1);
public static void main(String[] args) {
synchronized (foo) {
foo.notifyAll();
}
System.out.println("Success");
}
вывод:
Успех