Java Threads with Boss-Worker
-
04-07-2021 - |
문제
I have to do schoolwork, and I have some code done, but got some questions:
must create a boss-workers application in java.
- I have these classes:
Main WorkerThread BossThread Job
Basically what I want to do is, that BossThread
holds a BlockingQueue
and workers go there and look for Jobs
.
Question 1:
At the moment I start 5 WorkingThreads
and 1 BossThread
.
Main:
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;
}
Is this normal, or I should create WorkerThreads
in my BossThread
?
Question 2:
As you see I am giving the queue to each WorkerThread
, is that reasonable or I could store the queue only in one place?
Question 3:
Must I keep my BossThread
running somehow, just to wait if user adds more stuff to queue? And how I keep WorkerThreads
running, to look for jobs from queue?
Any overall suggestions or design flaws or suggestions?
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;
}
}
해결책
Firstly, one important mistake I noticed:
BossThread thread = new BossThread(jobs, workers));
thread.run();
Runnable
s must be passed to a Thread
object and threads are started with start
, not run
. By calling run
you get sequential execution on the same thread. So:
Thread thread = new Thread(new BossThread(jobs, workers)));
thread.start();
Secondly, unless you absolutely must use BlockingQueue
and explicit threads I would instead use ExecutorService
. It neatly encapsulates a blocking work queue and a team of workers (whose size you can set). It's basically what you're doing but much simpler to use:
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());
}
And that's it! All the put
and take
stuff is handled by the executor automatically.