Почему notifyAll () вызывает IllegalMonitorStateException при синхронизации с Integer?

38
задан erickson 31 May 2017 в 03:57
поделиться

3 ответа

Вы отметили правильно, что notifyAll должен быть назван от синхронизируемого блока.

Однако в Вашем случае, из-за автоупаковки, объект, на котором Вы синхронизировались, не является тем же экземпляром, на который Вы вызвали notifyAll. На самом деле, новое, увеличенное foo, экземпляр все еще ограничен стеком, и никакие другие потоки не могли возможно быть заблокированы на wait вызов.

Вы могли реализовать свой собственный, изменяемый счетчик, на котором выполняется синхронизация. В зависимости от Вашего приложения Вы могли бы также найти, что AtomicInteger удовлетворяет Ваши потребности.

54
ответ дан erickson 31 May 2017 в 03:57
поделиться

Необходимо также быть подозрительной блокировкой или уведомлением относительно объектов как Строка и Целое число, которое может быть интернировано JVM (для предотвращения создания большого количества объектов, которые представляют целое число 1 или строка"").

3
ответ дан dbt 31 May 2017 в 03:57
поделиться

Поскольку erickson отметил, код без постинкрементных работ оператора без ошибки:

static Integer foo = new Integer(1);

public static void main(String[] args) {
    synchronized (foo) {
        foo.notifyAll();
    }
    System.out.println("Success");
}

вывод:

Успех

1
ответ дан matt b 31 May 2017 в 03:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: