[英]Wait and Notify problem with many threads
我对方法wait()
和notify()
有问题。 我有三个线程,一个叫做Management
(负责管理其他线程),两个叫做Worker
,两个类都实现了Runnable
。 Management
为每个Worker
提交一项任务并继续工作。 Worker
,当收到任务时需要处理该任务并等待其他任务。
在我的Management
中,我有一个名为doWork
的方法,它基本上将任务发送给Workers
并通知他们。 所有实现描述如下:
WorkerManagement(请考虑实现构造函数和其他方法):
public class WorkerManagement extends ActiveObject{
private volatile Map<Worker, Boolean> workers = new HashMap<>();
@Override
protected void doWork() {
while(!mustStop()){
if(getAvailableThreadsSize() != workers.size()){
continue;
}
WorkQueue highestPriorityWorkQueue = workQueues.getHighestPriorityWorkQueue();
if(highestPriorityWorkQueue == null){
continue;
}
tasks = highestPriorityWorkQueue.pollList();
for (Map.Entry<Worker, Boolean> entry : workers.entrySet()) {
Worker worker = entry.getKey();
worker.updateTask(tasks.poll());
workers.replace(worker, Boolean.FALSE);
synchronized (worker) {
worker.notify();
}
}
}
}
private int getAvailableThreadsSize(){
int availables = 0;
for (Map.Entry<Worker, Boolean> entry : workers.entrySet()) {
Boolean available = entry.getValue();
if(available){
availables++;
}
}
return availables;
}
}
Worker(请考虑实现构造函数和其他方法):
public class Worker extends ActiveObject{
private WorkerManagement workerManagement;
private Task task;
@Override
protected void doWork() {
while (!mustStop()) {
System.out.println(Thread.currentThread().getName()+" is Alive:"+Thread.currentThread().isAlive());
try {
task.execute();
workerManagement.setAvailable(this);
synchronized(this){
System.out.println(Thread.currentThread().getName()+" is Alive:"+Thread.currentThread().isAlive());
wait();
}
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Exception in Worker: " + getName(), ex);
}
}
}
}
PS: ActiveObject
是实现Runnable
的内部 class 。
@EDIT:我的问题,基本上是:一个工人总是在等待,另一个总是活着。 所以,当我在WorkerManagement
上调试代码时, getAvailableThreadsSize
方法总是返回 1, workers.size()
总是返回 2。我的doWork
打印的 output 的一个例子是:
WorkerThread-1 is Alive:true
WorkerThread-2 is Alive:true
WorkerThread-2 is Alive:true
WorkerThread-2 is Alive:true
WorkerThread-2 is Alive:true
这意味着 WorkerThread-2 始终在工作,而 WorkerThread-1 正在等待(第一次执行除外)。
用这段代码
if (getAvailableThreadsSize() != workers.size()){
continue;
}
如果这是一个正在运行的线程,则可用线程的数量将为workers.size()-1,因此只能激活一个线程
尝试更改为
if (getAvailableThreadsSize() >0){
continue;
}
实际上问题是因为任务是null
并且它在进入同步块之前抛出了错误。 我修复了它在一段时间开始时添加和验证:
if(workUnitToProcess == null){
synchronized (this) {
workerManagement.setAvailable(this);
wait();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.