我必须做功课,我已完成一些代码,但有一些问题:
必须在java中创建一个boss-workers应用程序。
Main WorkerThread BossThread Job
基本上我想要做的是,BossThread
持有BlockingQueue
,工作人员去那里寻找Jobs
。
问题1:
目前我开始5 WorkingThreads
和1 BossThread
。
主:
Collection<WorkerThread> workers = new ArrayList<WorkerThread>();
for(int i = 1; i < 5; i++) {
WorkerThread worker = new WorkerThread();
workers.add(worker);
}
BossThread thread = new BossThread(jobs, workers);
thread.run();
BossThread:
private BlockingQueue<Job> queue = new ArrayBlockingQueue<Job>(100);
private Collection<WorkerThread> workers;
public BossThread(Set<Job> jobs, Collection<WorkerThread> workers) {
for(Job job : jobs) {
queue.add(job);
}
for(WorkerThread worker : workers) {
worker.setQueue(queue);
}
this.workers = workers;
}
这是正常的,还是我应该在我的WorkerThreads
中创建BossThread
?
问题2:
如您所见,我将队列分配给每个WorkerThread
,这是合理的还是我只能将队列存储在一个地方?
问题3:
我必须让BossThread
以某种方式运行,只是等待用户添加更多东西到队列中吗?我如何保持WorkerThreads
运行,从队列中寻找工作?
有任何整体建议或设计缺陷或建议吗?
public class WorkerThread implements Runnable {
private BlockingQueue<Job> queue;
public WorkerThread() {
}
public void run() {
try {
queue.take().start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void setQueue(BlockingQueue<Job> queue) {
this.queue = queue;
}
}
答案 0 :(得分:1)
首先,我注意到一个重要的错误:
BossThread thread = new BossThread(jobs, workers));
thread.run();
Runnable
必须传递给Thread
个对象,并且线程以start
启动,而不是run
。通过调用run
,您可以在同一个线程上执行顺序执行。所以:
Thread thread = new Thread(new BossThread(jobs, workers)));
thread.start();
其次,除非你绝对必须使用BlockingQueue
和显式线程,否则我会使用ExecutorService
。它巧妙地封装了一个阻塞工作队列和一组工人(你可以设置它们的大小)。这基本上就是你正在做的事情,但更简单易用:
class Job implements Runnable {
public void run() {
// work
}
}
...
// create thread pool with 5 threads and blocking queue
ExecutorService exec = Executors.newFixedThreadPool(5);
// submit some work
for(int i = 0; i < 10; i++) {
exec.submit(new Job());
}
就是这样!所有put
和take
内容都由执行程序自动处理。