我总是很犹豫是否公开我的锁,公开它们。我总是试图将锁限制在我的实现中。我相信,不这样做会导致僵局。
我有以下课程:
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、...!您是否会介意监听器是否可以在未注册时收到通知。关键是你是否会把锁打开。这是关于避免或不避免死锁。
请分享你的想法。谢谢!