我必须做功课,我已经完成了一些代码,但有一些问题:
必须在 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();
老板线程:
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;
}
这是正常的,还是我应该在我的 BossThread
中创建 WorkerThreads
?
问题 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;
}
}
最佳答案
首先,我注意到一个重要的错误:
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
的东西都由执行器自动处理。
关于带有 Boss-Worker 的 Java 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12620297/