【问题标题】:Java Threads with Boss-Worker带有 Boss-Worker 的 Java 线程
【发布时间】:2012-09-27 11:26:29
【问题描述】:

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

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

  1. 我有这些课程: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;
    }
}

【问题讨论】:

  • 我会使用ExecutorService,它将队列与线程池结合起来,并将替换您的大部分代码。

标签: java multithreading runnable blockingqueue


【解决方案1】:

首先,我注意到一个重要错误:

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

Runnables 必须传递给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 的东西都由执行器自动处理。

【讨论】:

  • 但是我的 BossThread 实现了 Runnable,当我将 run 改为 start 时,我得到:The method start() is undefined for the type BossThread
  • @Jaanus:在开头查看我的编辑。这意味着您没有正确启动线程。您需要将Runnable 传递给Thread 对象。
  • 我的 Job 必须实现 Runnable 吗?目前它只是类,可以使用方法doWork(),并且只有实现runnable的东西是bossthread,workerthread。此外,每个 Workerthread 似乎都有这样的单独队列,而不是与老板共享队列。
  • @Jaanus:如果你使用ExecutorService,它必须实现Runnablesubmit 方法需要 RunnableExecutorService 只有一个共享队列,就像你的情况一样。
  • 但既然是我的功课,我想我必须自己实现一些东西,而不是使用服务。所以在我的例子中,似乎每个 Worker 都有一个队列,但我需要他们只使用 1 个队列。
猜你喜欢
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
  • 2020-06-01
  • 2020-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多