2017-07-06 162 views
-1

使用线程我有这样的代码:与观察者模式

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()方法本身中执行,因为它会在调用notifyObservers()的Observable的同一个线程中执行。 有什么方法可以将事件“发信号”给run()方法吗?

+1

使用的BlockingQueue。当update()被调用时发送队列中的事件。从run()中的BlockingQueue中读取事件。 –

回答

2

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

-1

在最基本的元素:为什么不只是使用您在更新中设置的一些membervariable/flag-Method?

eventWasFired = true; 

在运行里面的while循环()做这样的事情:

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

需要同步接入和使用一些原子变量,如果您有可以访问您观察到的多个线程。否则你的程序会暴露于数据竞赛。

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.