首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么选择可观察的快照观测器矢量

为什么选择可观察的快照观测器矢量
EN

Stack Overflow用户
提问于 2010-12-15 12:33:54
回答 4查看 453关注 0票数 2

在Observable的notifyObservers方法中,为什么编码器使用arrLocal = obs.toArray();?为什么程序员不直接迭代向量呢?谢谢

代码语言:javascript
复制
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);
}
EN

回答 4

Stack Overflow用户

发布于 2010-12-15 12:40:01

他们希望避免并发修改,但同时又不想在synchronized块中停留太长时间(特别是当他们不知道自己实际调用的是什么代码时)。

选项一是对整个操作进行同步,并在通知观察者的同时直接迭代向量。正如注释指出的(“我们不希望观察者在持有自己的监视器的同时回调到任意代码中”),这可能会使观察者锁定很长一段时间。

第二种选择是只同步足够长的时间,以获得向量的一致副本。然后,他们可以在迭代他们的私有副本之前释放锁。

更新:如果观察者更新了观察者列表,那么同时迭代它可能不是一个好主意。因此,即使在单线程情况下,也建议使用副本。

票数 2
EN

Stack Overflow用户

发布于 2010-12-15 12:43:51

这个帖子中的其他答案关于副本的目的是正确的。不过,我要说的是,Java 5+已经有了能够自动完成复制的正确数据结构:java.util.concurrent.CopyOnWriteArrayList

票数 1
EN

Stack Overflow用户

发布于 2010-12-15 12:41:12

编码器使用"obs.toArray()“来”快照“当前的观察者。他们试图防止在一个可能会改变的向量上进行迭代,而不是显式地围绕该向量进行同步。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4446718

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档