Это зависит от того, где вы получаете слушателя в вашем методе, сколько у вас слушателей, как подписчик подписывается / отписывается
Исходя из вашего примера, у вас есть только один слушатель, тогда вам может быть лучше использовать критические секции (или мониторы) для разных частей класса, а не блокировать весь объект.
У вас может быть одна блокировка для выполнения задач в рамках метода, специфичного для данного объекта / задачи, и одна для слушателя «подписаться / отписаться / уведомить» (это означает, что слушатель не изменяется во время уведомления) .
Я бы также использовал ReadWriteLock, защищающий ссылки на слушателей (один или список слушателей)
Отвечая на ваш комментарий:
Я думаю, что вы должны уведомить слушателя после того, как вы разблокировали класс. Это связано с тем, что результат этого уведомления может привести к тому, что другой поток попытается получить доступ к классу, что может быть невозможно при определенных обстоятельствах, что приведет к тупику.
Уведомление слушателя (если оно защищено, как я описал) не должно задерживать какой-либо другой поток, требующий средств класса. Наилучшей стратегией является создание блокировок, специфичных для состояния класса, и блокировок, специфичных для безопасного уведомления.
Если вы воспользуетесь своим примером приостановки уведомлений, это может быть закрыто блокировкой, которая управляет уведомлениями, поэтому, если другой поток «приостанавливает» уведомления, либо приостановится обработка, либо текущее уведомление завершится, если другой поток приостановит уведомление между обрабатываемой задачей и полученным уведомлением l.notify () не произойдет.
Listener l = null;
synchronised(processLock_) {
... do stuff....
synchronised(notifyLock_) {
l = listener;
}
}
//
// current thread preempted by other thread that suspends notification here.
//
synchronised(notifyLock_) { // ideally use a readwritelock here...
l = allowNotify_ ? l: null;
}
if(l)
l.notify();