我有以下情况: 多个事件来自源,每个事件都有不同的类型。我需要按顺序对相同类型的每个事件执行某些操作,如果是其他类型则需要并行处理。含义:
来自的来源: A1,A2,B1,A3,B2,C1
我在做什么来实现这个目标?一般来说,我有一个监视器,用于每种类型的事件,我用新线程初始化,然后调用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搜索我的问题的一些替代方案,但我找不到任何好的东西。你能否就如何解决这个问题给我任何建议?
我希望我能以一种好的方式解释我的问题。如果没有,请询问。
提前致谢。
答案 0 :(得分:5)
“killed”标志用于维持线程活动,直到满足某些条件。然后,我将kill标志设置为true并通知监视器结束线程。
首先,我会认真考虑将代码切换为BlockingQueue
,例如LinkedBlockingQueue
。您仍然可以使用killed
标志(必须是voltile
顺便说一句),但是使用BlockingQueue
可以为您处理所有信令。您所要做的就是调用put()
将内容添加到队列中,并take()
从中读取内容。然后,您无需使用synchronized
,wait
或notify
。您根本不需要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
布尔值时,才会这样做。