Jap*_* D. 3 java synchronized locks
我总是非常犹豫要把我的锁公开,让它们公开.我总是试图将锁限制在我的实现中.我相信,不这样做是一个僵局的秘诀.
我有以下课程:
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);
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
当SomeClass想要通知他的听众时,你会这样做:
synchronized (mListeners) {
for (Listener l : mListeners) {
l.event();
}
}
Run Code Online (Sandbox Code Playgroud)
要么
Listener[] listeners = null;
synchronized (mListeners) {
listeners = mListeners.toArray();
}
for (Listener l : listeners) {
l.event();
}
Run Code Online (Sandbox Code Playgroud)
我会选择第二种选择.缺点是听众可以获得活动,即使他们已经取消注册.好处是,一个侦听器calllback正在等待的线程,当他想取消注册一个监听器时,它不会遇到死锁.我认为好处比下行更重要,可以很容易地记录下来.
所以这里的问题基本上是:你会暴露你的锁吗?
我的问题不是你选择一个简单的ArrayList,LinkedList,ConcurrentLinkedQueue,CopyOnWriteArrayList,......!您是否会介意监听器是否可以在未注册时收到通知.无论你是否将锁打开,或不是.这是关于避免死锁.
请分享你的想法.谢谢!
使用a CopyOnWriteArrayList
作为侦听器数组.
这非常适合不经常更改的侦听器阵列.当您遍历它们时,您将遍历底层数组.使用a CopyOnWriteArrayList
,每次修改时都会复制此数组.所以在迭代时不需要与它同步,因为每个底层数组都保证是静态的,甚至超过它在其中的使用CopyOnWriteArrayList
.
由于CopyOnWriteArrayList
也是线程安全的,因此您无需同步添加和删除操作.
宣言:
private final CopyOnWriteArrayList<Listener> listeners;
Run Code Online (Sandbox Code Playgroud)
事件触发器:
for (Listener l: this.listeners) {
l.event();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4143 次 |
最近记录: |