与Boss-Worker的Java线程

时间:2012-09-27 11:26:29

标签: java multithreading runnable blockingqueue

我必须做功课,我已完成一些代码,但有一些问题:

必须在java中创建一个boss-workers应用程序。

  1. 我有这些课程:Main WorkerThread BossThread Job
  2. 基本上我想要做的是,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;
        }
    }
    

1 个答案:

答案 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());
}

就是这样!所有puttake内容都由执行程序自动处理。