我有4个观察者正在监听可观察的数据。然而,我的一个观察者是较慢的,可以采取。我刚看到notifyObserver的代码为: -
132 public void notifyObservers(Object arg) {
133 /*
134 * a temporary array buffer, used as a snapshot of the state of
135 * current Observers.
136 */
137 Object[] arrLocal;
138
139 synchronized (this) {
/**comment removed for clarity **/
152 if (!changed)
153 return;
154 arrLocal = obs.toArray();
155 clearChanged();
156 }
157
158 for (int i = arrLocal.length-1; i>=0; i--)
159 ((Observer)arrLocal[i]).update(this, arg);
160 }
从代码中可以看出,观察者是一个接一个地被调用的。由于设计观察者在执行中是独立的。不应该同时调用它们并将arg
作为最终版本吗?
执行时间t1+t2+t3+t4
应该是max(t1,t2,t3,t4)
。我可以使观察者的update
函数非阻塞,但这不会相同并且可能导致一些竞争条件,因为notifyObservers()
将在没有完全执行观察者的情况下退出。
我错过了这个设计背后的东西吗?这是故意的,我无法在这里减少时间吗?
答案 0 :(得分:6)
优化通知观察者的执行时间不是模式的一部分。具有长时间运行任务的观察者应该启动自己的执行线程并立即从update()
返回而不是阻止。
答案 1 :(得分:2)
上下文:Java中的Observer实现是一种通用实现设计,适用于许多,但不适用于所有情况。顺序调用update()
方法的主要原因是许多框架(例如GUI和可能的应用程序代码)被设计为单线程并且并行执行观察者肯定会导致一些竞争条件。
解决方案:在观察者的update()
方法(如Samuel解释)中的单独线程中执行逻辑,或者,如果您始终要并行执行update()
方法,创建您自己的实现并在ExecutorService
方法中使用notifyObservers()
。