我有多个workerThreads和一个producerThread。当我运行下面的代码时,很少运行工作线程。我得到的输入就像;
workToDo Size: 1
workToDo Size: 2
...
workToDo Size: 514
91 removed //First remove output
workToDo列表正在增加。有没有办法减少工作线程的运行间隔?我想我在这里做错了。
我的主要方法;
WorkerThread workerThread = new WorkerThread();
WorkerThread workerThread2 = new WorkerThread();
WorkerThread workerThread3 = new WorkerThread();
ProducerThread producerThread = new ProducerThread();
workerThread.producerThread = producerThread;
workerThread2.producerThread = producerThread;
workerThread3.producerThread = producerThread;
producerThread.start();
workerThread.start();
workerThread2.start();
workerThread3.start();
的WorkerThread;
public class WorkerThread extends Thread {
ProducerThread producerThread;
@Override
public void run() {
while (true) {
synchronized (producerThread) {
try {
producerThread.wait();
System.out.println(producerThread.workToDo.remove(0) + " removed");
} catch (InterruptedException ex) {
}
}
}
}
}
ProducerThread;
public class ProducerThread extends Thread {
List<Integer> workToDo = new ArrayList();
@Override
public void run() {
while (true) {
synchronized (this) {
workToDo.add((int)(Math.random() * 100));
System.out.println("workToDo Size: " + workToDo.size());
notifyAll();
}
}
}
}
答案 0 :(得分:2)
workToDo列表正在增加。有没有办法减少工作线程的运行间隔?我想我在这里做错了。
没有看到更多的代码,很难完全回答,但这似乎是一个典型的问题,当你的生产者线程可以比消费者处理它们更快地产生工作。您应该使用有界 BlockingQueue
,这样您才能排队一定数量的请求,而不是用它们填充内存。
您应该考虑将ExecutorService
classes与有界队列一起使用。例如:
// start a thread pool with 3 worker threads and a queue of 100
ExecutorService threadPool =
new ThreadPoolExecutor(3, 3, 0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<Runnable>(100));
// to get the producer to _block_ instead of rejecting the job you need a handler
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
// this will cause the producer to block until there is room in queue
executor.getQueue().add(r);
}
});
你的生产者线程,如果你将线程数增加到4,它也可以是在threadPool中运行的作业,然后只需将Runnable
个作业提交给你的线程池,由3个工作线程处理。如果3忙,那么它将在ArrayBlockingQueue
中排队请求。一旦100(随意更改该号码)作业排队,生产者将阻止,直到另一个作业完成。
使用ExecutorService
和BlockingQueue
意味着所有难以理解的等待和通知逻辑都会为您完成。