线程没有通知通知

时间:2013-06-25 13:33:24

标签: java multithreading

我有以下情况: 多个事件来自源,每个事件都有不同的类型。我需要按顺序对相同类型的每个事件执行某些操作,如果是其他类型则需要并行处理。含义:

来自的来源: A1,A2,B1,A3,B2,C1

  • 监听器A,必须排队A1,A2和A3,并在其中使用它们 订单,单线程
  • 监听器B与A相同,并行,在不同的线程中
  • 侦听器C与B相同,并行,在不同的线程中

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

Monitor.java(实现runnable)

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();
  }
}

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

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

我一直在寻找并发api搜索我的问题的一些替代方案,但我找不到任何好的东西。你能否就如何解决这个问题给我任何建议?

我希望我能以一种好的方式解释我的问题。如果没有,请询​​问。

提前致谢。

1 个答案:

答案 0 :(得分:5)

  

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

首先,我会认真考虑将代码切换为BlockingQueue,例如LinkedBlockingQueue。您仍然可以使用killed标志(必须是voltile顺便说一句),但是使用BlockingQueue可以为您处理所有信令。您所要做的就是调用put()将内容添加到队列中,并take()从中读取内容。然后,您无需使用synchronizedwaitnotify。您根本不需要stopped标志。见下文。

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

我的问题是当我运行一组事件时,有时线程没有使用notify()唤醒。有时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布尔值时,才会这样做。