синхронизированные (это) и уведомления наблюдателей - PullRequest
2 голосов
/ 13 апреля 2011

Это связано, но определенно не идентично, с этим знаменитым вопросом SO:

Избегать синхронизации (это) в Java?

Очень часто у меня есть "наблюдаемый субъект", который любит уведомлять своих наблюдателей, когда он изменяется. Уведомление в основном вызывает "чужой метод" (как они называются в Effective Java и т. Д.). У меня может быть что-то вроде этого:

public void updateData(params) {
    synchronized (this) {
        // do some computation here
    }
    notifyObservers(); // Never, EVER, call an alien method with a lock held (see Effective Java)
}

public synchronized Result getResult() {
   ...
}

Должен ли я избегать synchronized(this) и, следовательно, также удалить synchronized из getResult() метода?

Это то, что люди, которые советуют против synchronized(this), рекомендуют:

private final Object lock = new Object(); // shiny lock

public void updateDate(params) {
    synchronized( lock ) {
       ...
    }
    notifyObservers();
}

public Result getResult() {
    synchronized( lock ) {
        return Result;
    }
}

В качестве дополнительного вопроса, который не оправдывает его собственный вопрос SO: если последний рекомендуется, что люди, которые не советуют использовать synchronized (this) , думают о том, что методы в Java могут быть объявлен как "синхронизированный"?

1 Ответ

1 голос
/ 11 января 2012

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

Обратите внимание, что существует другая, гораздо более гибкая альтернатива: ReentrantLock.Один из недостатков внутренних замков, не упомянутых в вопросе, который вы упомянули, заключается в том, что они поддерживают только получение непрерывного замка.С другой стороны, ReentrantLock предоставляет методы для проверки состояния блокировки, прерываемого захвата и захвата с тайм-аутом.

Прерываемое обнаружение особенно полезно при написании отменяемых задач, поскольку оно следует общему предписанию для методов блокировки, генерирующих InterruptedException, чтобы сигнализировать о прерывании потока в операции блокировки.За механизмом отмены, основанным на прерывании, следуют Исполнители из java.util.concurrent .

...