Я использую библиотеку CMU Sphinx Speech Recognizer ( Ссылка на источник ), которая в некоторой степени использует синхронизированные
блоки.
Один пример блока из RecognizerTask:
Event mailbox;
[...]
public void start() {
synchronized (this.mailbox) {
this.mailbox.notifyAll();
this.mailbox = Event.START;
}
}
Код работает без проблем, однако BugFinder выдает следующее предупреждение:
Ошибка: синхронизация на RecognizerTask.mailbox при тщетной попытке guard it
Этот метод синхронизирует поле в том, что кажется попытаться защититься от одновременных обновлений этого поля. Но защита поля получает блокировку на объект, на который указывает ссылка, а не на поле. Это может не обеспечить необходимого вам взаимного исключения, и другие потоки могут получать блокировки на ссылочных объектах (для других целей).Примером этого шаблона может быть:
private Long myNtfSeqNbrCounter = new Long (0); private Long getNotificationSequenceNumber () { Длинный результат = null; синхронизировано (myNtfSeqNbrCounter) { результат = новый Long (myNtfSeqNbrCounter.longValue () + 1); myNtfSeqNbrCounter = новый Long (result.longValue ()); } вернуть результат; }
Честно говоря, я не совсем понимаю описание ошибки и то, что должно быть неправильным в этом случае. Глобальная переменная - это не поле? А если нет, как я могу улучшить код?
/ edit: Это единственная часть, где вызывается Event.wait ()
:
Event todo = Event.NONE;
synchronized (this.mailbox) {
todo = this.mailbox;
/* If we're idle then wait for something to happen. */
if (state == State.IDLE && todo == Event.NONE) {
try {
//Log.d(getClass().getName(), "waiting");
this.mailbox.wait();
todo = this.mailbox;
//Log.d(getClass().getName(), "got" + todo);
} catch (InterruptedException e) {
/* Quit main loop. */
//Log.e(getClass().getName(), "Interrupted waiting for mailbox, shutting down");
todo = Event.SHUTDOWN;
}
}
/* Reset the mailbox before releasing, to avoid race condition. */
this.mailbox = Event.NONE;
}
Этот код фактически использует также синхронизированный оператор
. Есть ли вообще смысл его использовать?