我总是很犹豫要把我的锁公开,让他们公开。我总是试图将锁限制在我的实现中。我相信,不这样做,是僵局的秘诀。我应该同步侦听器通知吗?
我有以下类:
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();
}
我会选择第二个选项。缺点是听众可以获得事件,即使他们已经没有注册。好处在于,一个侦听器calllback正在等待的线程在他想要注销一个侦听器时不会遇到死锁。我认为上涨比下跌更重要,这可以很容易地记录下来。
所以这里的问题基本上是:你会暴露你的锁吗?
我的问题是,如果你会选择一个普通的ArrayList,LinkedList,ConcurrentLinkedQueue,CopyOnWriteArrayList,...!您是否会介意听众是否可以在未注册时收到通知。你是否会把锁打开,或者没有。这是关于避免死锁,或者不。
请分享您的想法。谢谢!
使用[synchronizedList](http://docs.oracle.com/javase/6/docs/api/java/util/Collections html的#synchronizedList(java.util.List中))。对于通知,循环周围的同步块很好。 – aishwarya
'CopyOnWriteArrayList'适用于遍历比更新更普遍的情况。 – artbristol
请阅读我的编辑。这是关于锁,而不是关于容器。 –