sup*_*sad 5 java design-patterns observer-pattern
在观察者设计模式中,主体通过调用update()每个观察者的操作来通知所有观察者.一种方法是这样做
void notify() {
for (observer: observers) {
observer.update(this);
}
}
Run Code Online (Sandbox Code Playgroud)
但是这里的问题是每个观察者都按顺序更新,观察者的更新操作可能不会被调用,直到更新之前的所有观察者.如果有一个观察者有一个无限循环的更新,那么它之后的所有观察者将永远不会得到通知.
题:
Ano*_*on. 20
问题是无限循环,而不是一个接一个的通知.
如果你想要同时更新内容,你需要在不同的线程上解决问题 - 在这种情况下,每个监听器都需要与其他监听器同步才能访问触发事件的对象.
抱怨一个无限循环阻止其他更新发生就像抱怨拿一个锁然后进入一个无限循环阻止其他人访问锁定对象 - 问题是无限循环,而不是锁管理器.
你可以使用java.utils.concurrent.Executors.newFixedThreadPool(int nThreads)方法,然后调用invokeAll方法(也可以使用带有timout的方法来避免无限循环).
您可以更改循环以添加一个Callable类,它接受"observer"和"this",然后在"call"方法中调用update方法.
这是我所说的快速而肮脏的实现:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main
{
private Main()
{
}
public static void main(final String[] argv)
{
final Watched watched;
final List<Watcher> watchers;
watched = new Watched();
watchers = makeWatchers(watched, 10);
watched.notifyWatchers(9);
}
private static List<Watcher> makeWatchers(final Watched watched,
final int count)
{
final List<Watcher> watchers;
watchers = new ArrayList<Watcher>(count);
for(int i = 0; i < count; i++)
{
final Watcher watcher;
watcher = new Watcher(i + 1);
watched.addWatcher(watcher);
watchers.add(watcher);
}
return (watchers);
}
}
class Watched
{
private final List<Watcher> watchers;
{
watchers = new ArrayList<Watcher>();
}
public void addWatcher(final Watcher watcher)
{
watchers.add(watcher);
}
public void notifyWatchers(final int seconds)
{
final List<Watcher> currentWatchers;
final List<WatcherCallable> callables;
final ExecutorService service;
currentWatchers = new CopyOnWriteArrayList<Watcher>(watchers);
callables = new ArrayList<WatcherCallable>(currentWatchers.size());
for(final Watcher watcher : currentWatchers)
{
final WatcherCallable callable;
callable = new WatcherCallable(watcher);
callables.add(callable);
}
service = Executors.newFixedThreadPool(callables.size());
try
{
final boolean value;
service.invokeAll(callables, seconds, TimeUnit.SECONDS);
value = service.awaitTermination(seconds, TimeUnit.SECONDS);
System.out.println("done: " + value);
}
catch (InterruptedException ex)
{
}
service.shutdown();
System.out.println("leaving");
}
private class WatcherCallable
implements Callable<Void>
{
private final Watcher watcher;
WatcherCallable(final Watcher w)
{
watcher = w;
}
public Void call()
{
watcher.update(Watched.this);
return (null);
}
}
}
class Watcher
{
private final int value;
Watcher(final int val)
{
value = val;
}
public void update(final Watched watched)
{
try
{
Thread.sleep(value * 1000);
}
catch (InterruptedException ex)
{
System.out.println(value + "interupted");
}
System.out.println(value + " done");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4244 次 |
| 最近记录: |