2013-06-25 53 views
0

我有以下情形: 多个事件来自源,每个都有不同的类型。我需要按顺序对同一类型的每个事件进行一些操作,如果是其他类型,则需要并行操作。含义:线程没有通知通知

从源活动: A1,A2,B1,A3,B2,C1

  • 监听器A,必须排队A1,A2和A3,并且在 顺序与他们的工作,以单个线程
  • 监听乙A相同,并行地,在不同的线程
  • 监听器C与B相同,并行地,在不同的线程

我在做什么来实现吨他?一般来说,我有一个监视器,每种类型的事件,我用一个新的线程初始化,然后调用wait()。每个监视器都有一个队列。

Monitor.java(实现可运行)

public void run(){ 
    while(!killed){ 
    synchronize(this){  
     while(this.stopped){ 
     wait(); //it waits here when initialized, waiting for the first event 
     } 

     while(eventQueue.size() > 0){ 
     //do something with the event 
     } 

     //i set the flag stopped = true again to wait for the next event 
     this.stopped = true; 
    } 
    } 
} 

当一个事件到达时,我将其添加到队列中,然后通知()显示器以它打破了,同时

public void awake(Event event){ 
    synchronize(this){ 
    eventQueue.add(event); 
    this.stopped = false; 
    notify(); 
    } 
} 

的“杀死”标志用于维持线程活着直到满足某些标准。然后,我将死亡标志设置为true,并通知监视器结束线程。

我的问题是当我运行一组事件,有时线程不会唤醒notify()。有时10个事件中有10个会被处理,有时候会是10个事件中的8个,依此类推。

我一直在寻找通过并行api寻找一些替代我的问题,但我找不到任何好的。你们能否就我如何应对这个问题给我任何建议?

我希望我能很好地解释我的问题。如果没有,请询​​问。

在此先感谢。

+0

供参考:this.stopped需要是volatile,因为它被多个线程使用。 – Gray

+0

'notify()'或'notifyAll()'? – Raedwald

回答

5

“杀死”标志用于维持线程处于活动状态,直到满足某些条件。然后,我将死亡标志设置为true,并通知监视器结束线程。

首先,我会认真考虑切换您的代码使用BlockingQueue,如LinkedBlockingQueue。你仍然可以使用killed标志(它必须是voltile btw),但是通过使用BlockingQueue所有的信号都是为你处理的。你所要做的就是致电put()将事情添加到队列中,并从take()中读取。然后您不需要使用​​,waitnotify。您根本不需要stopped标志。见下文。

while (!killed) { 
    Event event = eventQueue.take(); 
    ... 

我的问题是,当我运行一组事件,有时线程不清醒与通知()。有时10个事件中有10个会被处理,有时候会是10个事件中的8个,依此类推。

从目前的代码错误的角度来看,我没有看到任何问题,但魔鬼是在细节。有一点要记住的是,如果线程A调用notify(),则线程B调用wait()通知已经丢失。我想你想要做的事,如下列:

while(!killed){ 
    Event event; 
    synchronized (this) { 
     // wait until where is something in the queue 
     while(eventQueue.isEmpty()){ 
      this.wait(); 
     } 
     event = eventQueue.get(); 
    } 
    // work with event 
    ... 

这只会如果队列为空,方式,它不需要stopped布尔。

+0

当我将事件放在队列中时,我是否必须做特别的事情? (调用notify?),或者仅仅通过告诉eventQueue.put(event)将假设唤醒线程? – GoVeM

+0

您需要放置(...)'然后调用'notify()'来唤醒正在等待@GoVeM的用户_if。如果你正在使用'BlockingQueue',那么你不需要执行'notify()'。 – Gray

+0

我实际上正在尝试使用'BlockingQueue'的解决方案,但是当我放置事件时,线程仍处于等待状态。 – GoVeM