我有一个多线程多对象系统,其中我有一个manager
和多个workers
。我需要将workers
与manager
同步,如下所示:
manager
做某事,将订单发给workers
,然后让workers
并行运行,彼此独立。当他们完成这一轮时,他们必须等待manager
给他们新的任务或命令。 manager
仅在所有workers
完成之前的工作时才会发出新订单。
我需要使用线程来实现它,以避免忙等待。然而,同步令人困惑。
有什么想法吗?
答案 0 :(得分:1)
编辑:我错过了一个重要部分,说新任务只有在完成后才会到达。因此,使用LinkedBlockingQueue不是最佳解决方案。我建议使用CyclicBarrier boris-the-spider推荐。
您可以使用LinkedBlockingQueue
设定固定容量。
答案 1 :(得分:0)
正如@boristhespider建议的那样,我对manager
和workers
使用了CyclicBarrier。
每个worker
完成任务后,会调用barrier.await()
。然后,对于manager
,我会检查是否barrier.getNumberWaiting()==NumWorkers
。如果是true
,则会更新每个worker
的任务,然后调用barrier.await()
。
答案 2 :(得分:0)
维护2个阻塞队列 1.任务 2.对于自由职业者
让工作人员通过回调通知经理,将其添加到免费工作人员队列
在内部经理线程中,您可以检查可用的工作人员。
快速实施
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();
}
}
}
}