Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多个对象之间的java线程同步_Java_Multithreading_Synchronization - Fatal编程技术网

多个对象之间的java线程同步

多个对象之间的java线程同步,java,multithreading,synchronization,Java,Multithreading,Synchronization,我有一个多线程多对象系统,其中有一个管理器和多个工作者。我需要将工作人员与经理同步,如下所示: manager做某事,给workers下命令,然后让workers独立并行运行。当他们完成这一轮时,他们必须等待经理给他们新的任务或订单。经理仅当所有的工人都完成了他们以前的工作时才发布新订单 我需要使用线程来实现它,以避免繁忙的等待。然而,同步是令人困惑的 有什么想法吗?编辑:我遗漏了一个重要的部分,即新任务只有在所有任务完成后才能到达。因此,使用LinkedBlockingQueue不是最佳解决方

我有一个多线程多对象系统,其中有一个
管理器
和多个
工作者
。我需要将
工作人员
经理
同步,如下所示:

manager
做某事,给
workers
下命令,然后让
workers
独立并行运行。当他们完成这一轮时,他们必须等待
经理
给他们新的任务或订单。
经理
仅当所有的
工人
都完成了他们以前的工作时才发布新订单

我需要使用线程来实现它,以避免繁忙的等待。然而,同步是令人困惑的


有什么想法吗?

编辑:我遗漏了一个重要的部分,即新任务只有在所有任务完成后才能到达。因此,使用LinkedBlockingQueue不是最佳解决方案。我建议使用spider推荐的自行车手boris

你可以使用

设置固定容量


manager
可以执行任务,
workers
可以使用函数等待。

正如@boristesspider所建议的,我对
manager
workers
都使用了CyclicBarrier

每个
工作者完成任务后,调用
barrier.await()
。然后,对于
管理器
,我检查
barrier.getNumberWaiting()==NumWorkers
。如果为
true
,它将更新每个
工作者的任务,然后调用
barrier.await()
维护2个阻塞队列 1.任务 2.免费工人

让工人通过回调通知经理,回调将他们添加到空闲工人队列

在manager线程中,您可以检查可用的工作人员

快速实施

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

public class ManagerWorker {
    public static void main(String[] args) {

        ExecutorService service = Executors.newCachedThreadPool();
        BlockingQueue<String> taskQueue = new LinkedBlockingQueue<>();

        Manager m = new Manager(5, taskQueue);
        service.submit(m);

        for (int i = 0; i < 5; i++) {
            service.submit(new Worker(m, taskQueue));
        }

    }
}

class Manager implements Runnable {

    int workerCount;
    BlockingQueue<Worker> workerqueue = new LinkedBlockingQueue<>();
    BlockingQueue<String> taskQueue;

    public Manager(int workerCount, BlockingQueue<String> taskQueue) {
        this.workerCount = workerCount;
        this.taskQueue = taskQueue;
    }

    public void callBackForFreeNotification(Worker worker) {
        workerqueue.add(worker);
    }

    @Override
    public void run() {
        while (true) {
            try {
                int i = 0;
                while (i < workerCount) {
                    workerqueue.take();
                    i++;
                }

                System.out.println("Manager Worker available");

                // add task to task queue here
                for (int j = 0; j < workerCount; j++) {
                    taskQueue.add("task");
                }
                System.out.println("Manager task added");
            } catch (InterruptedException e) {

                e.printStackTrace();
            }
        }
    }

}

class Worker implements Runnable {

    private Manager manager;
    private BlockingQueue<String> taskQueue;

    public Worker(Manager manager, BlockingQueue<String> taskqueue) {
        this.manager = manager;
        this.taskQueue = taskqueue;
    }

    @Override
    public void run() {
        while(true){


        try {

            System.out.println("Worker - i have no work");
            manager.callBackForFreeNotification(this);
            taskQueue.take();
            System.out.println("Worker working");
            Thread.sleep(2000);
            System.out.println("Worker Done with work");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        }
    }

}
import java.util.concurrent.BlockingQueue;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.LinkedBlockingQueue;
公共类管理员{
公共静态void main(字符串[]args){
ExecutorService=Executors.newCachedThreadPool();
BlockingQueue taskQueue=新建LinkedBlockingQueue();
经理m=新经理(5,任务队列);
服务。提交(m);
对于(int i=0;i<5;i++){
提交(新工人(m,任务队列));
}
}
}
类管理器实现可运行的{
国际工人计数;
BlockingQueue workerqueue=新建LinkedBlockingQueue();
阻塞队列任务队列;
公共管理器(int workerCount、BlockingQueue taskQueue){
this.workerCount=workerCount;
this.taskQueue=taskQueue;
}
公共作废callBackForFreeNotification(工作者){
workerqueue.add(worker);
}
@凌驾
公开募捐{
while(true){
试一试{
int i=0;
而(i
我有很多想法;我可以给你一天的价格。否则,编写一些代码,找出您遇到的问题;然后发到这里寻求帮助。我们不是代码编写服务。提示:看看。@BoristheSpider,我当然不想要代码编写服务。只是一个提示。CyclicBarrier解决了这个问题。如果您能描述一下为什么经理只在所有员工完成工作后才发布新订单,这会有所帮助。@Sidias Korrado员工正在使用共享资源。资源应该在分配新订单之前释放。排序:我假设如果您有
n
任务和
n
工作人员-并且任务需要足够长的时间才能运行-那么当您将
n
任务发布到
阻塞队列
时,将让每个工作人员执行一个任务并处理它。但这并不能解决主人等工人的问题。使用非常简单的方法,OP可能会更好。主机可以通过查看
queue.size()>=n
来等待工人,然后再等待一会儿。或者工人们可以发出他们的状态信号,有很多方法可以做到。这是行不通的,除非工人们把东西放回另一个队列——所以你需要两个队列。我不是说你的方法行不通,我只是说你在重新发明轮子;对于并发代码来说,这通常是一个非常糟糕的想法。
ExecutorService
代码是JDK的一部分,因此经过了很好的测试。而且它确实做了需要的事情……我很好奇为什么您认为
queue.size()>=n
解决方案不起作用。该队列包含等待执行的任务。哪个队列?工作项队列在开始时的
大小为
n
,然后在完成所有工作后的大小为
0
。它将继续保持
大小
0
,除非将项目放回