Я всегда очень не решаюсь раскрыть свои замки, сделать их публичными.Я всегда стараюсь ограничивать блокировки моей реализацией.Я полагаю, что не делать этого - это рецепт тупиков.
У меня есть следующий класс:
class SomeClass {
protected ArrayList<Listener> mListeners = new ArrayList<Listener>();
protected void addListener(Listener listener) {
synchronized (mListeners) {
mListeners.add(listener);
}
}
protected void removeListener(Listener listener) {
synchronized (mListeners) {
mListeners.remove(listener);
}
}
...
}
Когда SomeClass хочет уведомить своих слушателей, вы сделаете:
synchronized (mListeners) {
for (Listener l : mListeners) {
l.event();
}
}
или
Listener[] listeners = null;
synchronized (mListeners) {
listeners = mListeners.toArray();
}
for (Listener l : listeners) {
l.event();
}
Я бы выбрал второй вариант.Недостатком является то, что слушатели могут получать события, даже если они уже зарегистрированы.Положительным моментом является то, что поток, на котором ожидает ответный вызов слушателя, не может зайти в тупик, когда он хочет отменить регистрацию слушателя.Я считаю, что преимущество гораздо важнее, чем недостаток, который легко документировать.
Таким образом, вопрос здесь в основном: вы выставите свой замок или нет?
Мойвопрос НЕ в том случае, если вы выбрали бы простой ArrayList, LinkedList, ConcurrentLinkedQueue, CopyOnWriteArrayList, a ...!Не возражаете ли вы, если слушатель может получить уведомление, пока оно уже не зарегистрировано.Будет ли вы открыть замок или нет.Речь идет о том, чтобы избежать тупиков или нет.
Пожалуйста, поделитесь своими мыслями.Спасибо!