对于传统的Producer-Consumer问题,我们可以使用ExecutorService作为队列。有什么缺点呢?效率低下吗?因为线程的创建成本很高。
executor = Executors.newFixedThreadPool(90);
// This will be called many times concurrently
public void processObjectsWithFixedSetOfThreads(Foo objectToProcess) {
//Create a new thread and submit (executor is of fixed size hence extra tasks will be queued)
executor.submit(new ObjectProcessorWorker(objectToProcess));
}
class ObjectProcessorWorker implements Runnable() {
public ObjectProcessorWorker(Foo obj) {
this.obj = obj;
}
public void run() {
longRunningProcess(obj);
}
}
为什么{@ 3}}建议用于生产者 - 消费者问题但是也可以BlockingQueue完成(如上所示)?
许多人没有得到差异,因为ThreadPoolExecutor在内部维护了BlockingQueue。
在饼干工厂,有一个包装饼干的任务。如果我是它的拥有者,我有两种方法来加快包装任务。
在装配线上放置饼干和包装纸,有10名工人在做包装工作。
我 - > queue.put(biscuits, wrapper)
工人 - > queue.take()
创建一个包裹饼干的任务,将它放在装配线上,然后让10名工人完成。
我 - > new Task(biscuits, wrapper)
工人 - > task = queue.take(); do(task);
我问的是后者的缺点。
答案 0 :(得分:1)
每当你定义ThreadPoolExecutore ..如下所示
ExecutorService threadPoolExecutor =
new ThreadPoolExecutor(
corePoolSize,
maxPoolSize,
keepAliveTime,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()
);
如果在将某个任务委托给线程池时在线程池中创建了少于 corePoolSize 线程,则会创建一个新线程,即使池中存在空闲线程也是如此。
如果任务的内部队列已满,并且正在运行corePoolSize或更多线程,但运行的线程少于 maximumPoolSize ,则会创建一个新线程来执行任务
现在,如果您已经定义阻塞队列 ...而不是 corePoolSize 之后,它会将新线程添加到队列中......直到达到队列容量。 在溢出队列之后,它将生成新的线程,直到 maximumPoolSize 。
不知道将ExecutorService用作队列有什么不利之处。我不认为有任何不利之处。
答案 1 :(得分:0)
使用Executors.newFixedThreadPool(int)
创建ThreadPoolExecutor
时,您正在创建BlockingQueue
:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
因此,你没有这样做&#34;没有&#34;如果您以这种方式创建的线程池,则为阻塞队列;它只是对你隐藏。