[英]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:我需要将
workers
与manager
同步,如下所示:
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 所建议的,我对
manager
和workers
都使用了 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.