简体   繁体   English

多线程的等待和通知问题

[英]Wait and Notify problem with many threads

I am having a problem with the methods wait() and notify() .我对方法wait()notify()有问题。 I have three threads, one is called Management (which is responsible for managing the others threads) and two called Worker , both classes implement Runnable .我有三个线程,一个叫做Management (负责管理其他线程),两个叫做Worker ,两个类都实现了Runnable The Management submit one task for each Worker and keep working. Management为每个Worker提交一项任务并继续工作。 The Worker , when recieve a task needs to process the task and wait for other task. Worker ,当收到任务时需要处理该任务并等待其他任务。

In my Management , I have a method called doWork , that basically send the tasks to the Workers and notify them.在我的Management中,我有一个名为doWork的方法,它基本上将任务发送给Workers并通知他们。 All implementation is described below:所有实现描述如下:

WorkerManagement (please, consider constructor and others methods implemented): 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 (please, consider constructor and others methods implemented): 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 is an inner class that implements Runnable . PS: ActiveObject是实现Runnable的内部 class 。

@EDIT: My problem, basically is: One worker is always waiting and the other is always alive. @EDIT:我的问题,基本上是:一个工人总是在等待,另一个总是活着。 So, when I debug the code on WorkerManagement the method getAvailableThreadsSize is always returning 1 and the workers.size() is returning 2. An example of output of my doWork print's is:所以,当我在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

Which means that the WorkerThread-2 is always working while WorkerThread-1 is waiting (except the first execution).这意味着 WorkerThread-2 始终在工作,而 WorkerThread-1 正在等待(第一次执行除外)。

Whit this code用这段代码

if (getAvailableThreadsSize() != workers.size()){
    continue;
}

if these is a thread running the number of available threads will be workers.size()-1 so only one thread can be activate如果这是一个正在运行的线程,则可用线程的数量将为workers.size()-1,因此只能激活一个线程

try to change to尝试更改为

if (getAvailableThreadsSize() >0){
    continue;
}

Actually the problem was becaus the task was null and it threw erros before entering on the synchronized block.实际上问题是因为任务是null并且它在进入同步块之前抛出了错误。 I fixed it adding and verification on the beggining of the while:我修复了它在一段时间开始时添加和验证:

if(workUnitToProcess == null){
    synchronized (this) {
        workerManagement.setAvailable(this);
        wait();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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