简体   繁体   English

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

[英]java thread sync between multiple objects

I have a multi-thread multi-object system in which I have a manager and multiple workers .我有一个多线程多对象系统,其中有一个manager和多个workers I need to synchronize the workers with the manager , like this:我需要将workersmanager同步,如下所示:

manager does sth, gives the order to the workers , and then let the workers run in parallel, independent of each other. manager做某事,给workers下达命令,然后让workers并行运行,相互独立。 When they finished this round, they must wait for the manager to give them the new task or order.当他们完成这一轮后,他们必须等待manager给他们新的任务或命令。 The manager issues the new order only if all the workers have finished their previous job.只有当所有workers都完成了他们之前的工作时, manager才会发布新订单。

I need to implement it using threads to avoid busy-waiting.我需要使用线程来实现它以避免忙等待。 However the synchronization is confusing.然而,同步令人困惑。

Any idea?任何的想法?

EDIT: i missed a important part that says new tasks should arrive only when all have finished.编辑:我错过了一个重要的部分,它说新任务只有在所有任务都完成后才能到达。 Therefore using LinkedBlockingQueue is not the best solution.因此使用 LinkedBlockingQueue 不是最好的解决方案。 I recommend using the CyclicBarrier boris-the-spider has recomended.我建议使用 CyclicBarrier boris-the-spider 推荐的。

You can use a LinkedBlockingQueue您可以使用LinkedBlockingQueue

Set a fixed capacity.设置固定容量。

The manager can put tasks, and the workers can use function take to wait. manager可以放置任务, workers可以使用函数take等待。

As @boristhespider suggested, I used CyclicBarrier for both manager and workers .正如@boristhespider 所建议的,我对managerworkers都使用了 CyclicBarrier 。

After each worker finishes its task, it calls barrier.await() .每个worker完成其任务后,它会调用barrier.await() Then for the manager , I check if barrier.getNumberWaiting()==NumWorkers .然后对于manager ,我检查是否barrier.getNumberWaiting()==NumWorkers If it's true , it updates the tasks of each worker and then calls barrier.await() .如果为true ,则更新每个worker的任务,然后调用barrier.await()

Maintain 2 Blocking queues 1. for Task 2. for free worker维护 2 个阻塞队列 1. 用于任务 2. 用于自由工作者

Let worker notify manager via a callback, which add them to free worker queue让工人通过回调通知经理,将他们添加到空闲工人队列

Inside manager thread you can check for workers available.在经理线程内部,您可以检查可用的工人。

quick implementation快速实施

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();
        }
        }
    }

}

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

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