[英]Using threads with Observer Pattern
我有这个代码:
public class classExample implements Observer Runnable {
public classExample() {
//...
}
@Override
public void run() {
while (true) {
//wait for EVENT;
//do something;
}
}
@Override
public void update(Observable arg0, Object arg1) {
//signal EVENT;
}
}
基本上,我希望我的线程在每次调用 update() 方法时都做一些事情。 我不能在 update() 方法本身中做,因为它会在 Observable 调用 notifyObservers() 的同一线程中执行。 有什么方法可以向 run() 方法“发出信号”事件?
您可以通过阻塞并发队列来实现消息传递。 然后classExample
线程可以等待阻塞以等待通过队列发送的新消息。 然后,当新消息到来时,该线程可以执行您最初想在 update 方法中执行的内容。
虽然其他人建议的阻塞队列可以工作,但我不是它的忠实粉丝,因为它需要忙等待(消费者循环无限轮询消息)。 另一种方法是每次Observer
收到通知时提交任务。
public class Main extends Observable implements Observer {
private final int numCores = Runtime.getRuntime().availableProcessors();
private final ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(numCores);
public Main() {
addObserver(this);
}
public static void main(String[] args) throws InterruptedException {
new Main().execute();
}
private void execute() {
for (int i = 0; i < 5; ++i) {
this.setChanged();
this.notifyObservers(i);
try {
Thread.sleep(1000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
}
@Override
public void update(Observable o, Object arg) {
System.out.printf("Received notification on thread: %s.\n", Thread.currentThread().getName());
executor.submit(() -> System.out.printf("Running in thread: %s, result: %s.\n",
Thread.currentThread().getName(), arg));
}
}
输出:
Received notification on thread: main.
Running in thread: pool-1-thread-1, result: 0.
Received notification on thread: main.
Running in thread: pool-1-thread-2, result: 1.
Received notification on thread: main.
Running in thread: pool-1-thread-3, result: 2.
Received notification on thread: main.
Running in thread: pool-1-thread-4, result: 3.
Received notification on thread: main.
Running in thread: pool-1-thread-5, result: 4.
如果你扩展线程类,你可以覆盖它的方法,然后你可以只使用 super() 然后做任何你想做的代码
在非常基本的元素上:为什么不使用您在更新方法中设置的一些成员变量/标志?
eventWasFired = true;
在 run() 内部的 while 循环中,执行以下操作:
try {
Thread.sleep(updateTimer);
if(eventWasFired) {
doSomeAction();
eventWasFired = false;
}
} catch (InterruptedException ie) {
// handle if you like
}
如果您有多个线程可以访问您的 observable,您需要同步访问并使用一些原子变量。 否则,您的程序将面临数据竞争。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.