使用具有观察者模式

时间:2017-07-06 21:21:39

标签: java observer-pattern java-threads

我有这段代码:

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()方法的事件?

4 个答案:

答案 0 :(得分:2)

您可以通过阻止并发队列来实现消息传递。然后,classExample线程可以等待阻止通过队列发送新消息。然后,当新消息出现时,该线程可以执行您最初想要在更新方法中执行的内容。

答案 1 :(得分:0)

虽然其他人建议的阻塞队列可行,但我不是它的忠实粉丝,因为它需要忙碌的等待(消费者循环无限轮询消息)。另一种方法是每次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.

答案 2 :(得分:0)

如果你扩展线程类,你可以覆盖它的方法,然后你可以只使用 super() 然后做任何你想做的代码

答案 3 :(得分:-1)

最基本的元素:为什么不使用你在update-Method中设置的某个membervariable / flag?

eventWasFired = true;

在run()内部的while循环中执行以下操作:

try {
    Thread.sleep(updateTimer);
    if(eventWasFired) {
         doSomeAction();
         eventWasFired = false;
    }
} catch (InterruptedException ie) {
    // handle if you like
}

如果有多个线程可以访问您的observable,则需要同步访问并使用一些原子变量。否则,您的程序将面临数据竞争。