3

I have to do schoolwork, and I have some code done, but got some questions:

must create a boss-workers application in java.

  1. 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;
    }
}
Jaanus
  • 16,161
  • 49
  • 147
  • 202

1 Answers1

1

Firstly, one important mistake I noticed:

BossThread thread = new BossThread(jobs, workers));
thread.run();

Runnables 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.

Tudor
  • 61,523
  • 12
  • 102
  • 142
  • But my BossThread implements Runnable, when I change run to start, then I get : `The method start() is undefined for the type BossThread` – Jaanus Sep 27 '12 at 12:17
  • @Jaanus: See my edit at the beginning. It means you are not starting the thread correctly. You need to pass the `Runnable` to a `Thread` object. – Tudor Sep 27 '12 at 12:18
  • Must my Job implement Runnable? At the moment it is just class, that does work with method `doWork()`, and only things that implement runnable are bossthread, workerthread. Furtheremore it seems that Workerthreads will each have individual queues like this, not shared queue with boss. – Jaanus Sep 27 '12 at 12:26
  • @Jaanus: It must implement `Runnable` if you use `ExecutorService`. The `submit` method expects a `Runnable`. There is only one shared queue with `ExecutorService`, like in your case. – Tudor Sep 27 '12 at 12:30
  • But since it is my schoolwork, I think I must implement some things myself, not use the service. So in my example, it seems like I will have a queue per Worker, but I need them to use only 1 queue. – Jaanus Sep 27 '12 at 12:32
  • @Jaanus: You are passing the same queue to all the workers so they all use the same queue. – Tudor Sep 27 '12 at 12:33