Java 为什么执行器创建执行器使用LinkedBlockingQueue而不是ConcurrentLinkedQueue publicstaticexecutorservice newFixedThreadPool(int-nThreads){ 返回新的ThreadPoolExecutor(第n个线程,第n个线程, 0L,时间单位为毫秒, 新建LinkedBlockingQueue()); }

Java 为什么执行器创建执行器使用LinkedBlockingQueue而不是ConcurrentLinkedQueue publicstaticexecutorservice newFixedThreadPool(int-nThreads){ 返回新的ThreadPoolExecutor(第n个线程,第n个线程, 0L,时间单位为毫秒, 新建LinkedBlockingQueue()); },java,concurrency,locking,java.util.concurrent,Java,Concurrency,Locking,Java.util.concurrent,使用LinkedBlockingQueue,但确实应该更有效,因为它没有阻塞和无锁?如果您向队列提交可运行对象,并且没有运行的线程来使用这些任务,它们当然不会被执行。当队列变空时,池必须阻塞并等待更多任务。因此,为了实现此行为,我们在与池交互时使用BlockingQueue。答案很简单:ConcurrentLinkedQueue不是BlockingQueue,而是LinkedBlockingQueue。ThreadPoolExecutorexpectBlockingQueues,这样Execut

使用LinkedBlockingQueue,但确实应该更有效,因为它没有阻塞和无锁?

如果您向队列提交可运行对象,并且没有运行的线程来使用这些任务,它们当然不会被执行。当队列变空时,池必须阻塞并等待更多任务。因此,为了实现此行为,我们在与池交互时使用BlockingQueue。

答案很简单:
ConcurrentLinkedQueue
不是
BlockingQueue
,而是
LinkedBlockingQueue
ThreadPoolExecutor
expect
BlockingQueue
s,这样
Executors
也会使用
BlockingQueue
的其他实现创建实例,如
SynchronousQueue
arrayblookingqueue
(取决于在
Executors
中调用的工厂方法)


因此,更普遍的问题是:为什么
阻塞队列
,而不是一个简单的
队列
。这里的答案也很简单:
BlockingQueue
接口有更多有用的方法。例如,一个方法告诉我们是否可以在不违反容量限制的情况下(并且不引发异常,检查)将元素插入队列中。或者,如果队列中没有元素,则某些方法会阻塞(队列中也有定时的
poll()
和非定时版本
take()
)。因此,如果您检查ThreadPoolExecutor的实现,您会看到它调用了
Queue
接口中遗漏的这些方便方法。

是的,没错,当没有任务有效时,worker(
getTask()
方法)将在workerQueue上被阻塞
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }