2013-11-25 4 views
1

Я вызываю метод notify() из синхронизированного блока, и я получаю java.lang.IllegalMonitorStateException. Я синхронизирован по этому конкретному объекту, поэтому я не вижу, где я ошибаюсь. Мой код таков:IllegalMonitorStateException on notify() call

public void setSynchronizer() { 
    synchronized (_synchronizer) { 
     _synchronizer = true; 
     _synchronizer.notify(); 
    }  
} 

Может кто-нибудь мне помочь, пожалуйста?

ответ

3

Я предполагаю, что _synchronizer является объектом Boolean. Когда вы делаете

_synchronizer = true; 

Компилятор решает true как объект ссылается Boolean.TRUE.

Если _synchronizer был Boolean.FALSE или другой объект Boolean, то вы имеете в виду другой объект. У вас нет монитора на этом объекте, поэтому notify() не работает.

Как указано в комментариях, вы не должны синхронизировать ссылку (объект), которая может измениться. Вы можете изменить состояние объекта, на которое ссылается переменная, но не ссылается на эту переменную. Хорошее место для начала - это только synchronized на final переменных.

+0

Это место, где примечание, что синхронизация на изменяемой переменной не является хорошей идеей, обычно должна быть добавлена. – Holger

+1

+1 «использовать« synchronized »только для« конечных »переменных» - хорошая мантра. Мне еще предстоит найти веские причины отклониться от этого правила. –

+0

Спасибо! Ваши комментарии мне очень помогли. Проблема заключалась в том, что назначение «_синхронизатор = истина»; назначил новый объект _синхронизатору, поэтому синхронизация уже недействительна. Я изменил _syncronizer на Boolean []. Новое состояние назначается _syncronizer [0], поэтому объект остается прежним. – user3032925