在Observable的notifyObservers方法中,为什么编码器使用arrLocal = obs.toArray();?为什么程序员不直接迭代向量呢?谢谢
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized (this) {
/* We don't want the Observer doing callbacks into
* arbitrary code while holding its own Monitor.
* The code where we extract each Observable from
* the Vector and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}发布于 2010-12-15 12:40:01
他们希望避免并发修改,但同时又不想在synchronized块中停留太长时间(特别是当他们不知道自己实际调用的是什么代码时)。
选项一是对整个操作进行同步,并在通知观察者的同时直接迭代向量。正如注释指出的(“我们不希望观察者在持有自己的监视器的同时回调到任意代码中”),这可能会使观察者锁定很长一段时间。
第二种选择是只同步足够长的时间,以获得向量的一致副本。然后,他们可以在迭代他们的私有副本之前释放锁。
更新:如果观察者更新了观察者列表,那么同时迭代它可能不是一个好主意。因此,即使在单线程情况下,也建议使用副本。
发布于 2010-12-15 12:43:51
这个帖子中的其他答案关于副本的目的是正确的。不过,我要说的是,Java 5+已经有了能够自动完成复制的正确数据结构:java.util.concurrent.CopyOnWriteArrayList。
发布于 2010-12-15 12:41:12
编码器使用"obs.toArray()“来”快照“当前的观察者。他们试图防止在一个可能会改变的向量上进行迭代,而不是显式地围绕该向量进行同步。
https://stackoverflow.com/questions/4446718
复制相似问题