Многопоточная корректность : Использование синхронизированного блока

Я использую библиотеку 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;
        }

Этот код фактически использует также синхронизированный оператор . Есть ли вообще смысл его использовать?

6
задан Force 9 January 2012 в 16:44
поделиться