繁体   English   中英

多线程的等待和通知问题

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM