@@ -234,12 +234,12 @@ static class Entry extends WeakReference<ThreadLocal<?>> {
234234
235235` Executors ` 返回线程池对象的弊端如下:
236236
237- - ` FixedThreadPool ` 和 ` SingleThreadExecutor ` :使用的是无界的 ` LinkedBlockingQueue ` ,任务队列最大长度为 ` Integer.MAX_VALUE ` , 可能堆积大量的请求,从而导致 OOM。
237+ - ` FixedThreadPool ` 和 ` SingleThreadExecutor ` :使用的是有界阻塞队列是 ` LinkedBlockingQueue ` ,其任务队列的最大长度为 ` Integer.MAX_VALUE ` , 可能堆积大量的请求,从而导致 OOM。
238238- ` CachedThreadPool ` :使用的是同步队列 ` SynchronousQueue ` , 允许创建的线程数量为 ` Integer.MAX_VALUE ` ,如果任务数量过多且执行速度较慢,可能会创建大量的线程,从而导致 OOM。
239- - ` ScheduledThreadPool ` 和 ` SingleThreadScheduledExecutor ` :使用的无界的延迟阻塞队列` DelayedWorkQueue ` ,任务队列最大长度为 ` Integer.MAX_VALUE ` , 可能堆积大量的请求,从而导致 OOM。
239+ - ` ScheduledThreadPool ` 和 ` SingleThreadScheduledExecutor ` :使用的无界的延迟阻塞队列 ` DelayedWorkQueue ` ,任务队列最大长度为 ` Integer.MAX_VALUE ` , 可能堆积大量的请求,从而导致 OOM。
240240
241241``` java
242- // 无界队列 LinkedBlockingQueue
242+ // 有界队列 LinkedBlockingQueue
243243public static ExecutorService newFixedThreadPool(int nThreads) {
244244
245245 return new ThreadPoolExecutor (nThreads, nThreads,0L , TimeUnit . MILLISECONDS ,new LinkedBlockingQueue<Runnable > ());
@@ -504,7 +504,7 @@ new RejectedExecutionHandler() {
504504
505505不同的线程池会选用不同的阻塞队列,我们可以结合内置线程池来分析。
506506
507- - 容量为 ` Integer.MAX_VALUE ` 的 ` LinkedBlockingQueue ` (无界队列 ):` FixedThreadPool ` 和 ` SingleThreadExector ` 。` FixedThreadPool ` 最多只能创建核心线程数的线程(核心线程数和最大线程数相等),` SingleThreadExector ` 只能创建一个线程(核心线程数和最大线程数都是 1),二者的任务队列永远不会被放满。
507+ - 容量为 ` Integer.MAX_VALUE ` 的 ` LinkedBlockingQueue ` (有界阻塞队列 ):` FixedThreadPool ` 和 ` SingleThreadExecutor ` 。` FixedThreadPool ` 最多只能创建核心线程数的线程(核心线程数和最大线程数相等),` SingleThreadExecutor ` 只能创建一个线程(核心线程数和最大线程数都是 1),二者的任务队列永远不会被放满。
508508- ` SynchronousQueue ` (同步队列):` CachedThreadPool ` 。` SynchronousQueue ` 没有容量,不存储元素,目的是保证对于提交的任务,如果有空闲线程,则使用空闲线程来处理;否则新建一个线程来处理任务。也就是说,` CachedThreadPool ` 的最大线程数是 ` Integer.MAX_VALUE ` ,可以理解为线程数是可以无限扩展的,可能会创建大量线程,从而导致 OOM。
509509- ` DelayedWorkQueue ` (延迟队列):` ScheduledThreadPool ` 和 ` SingleThreadScheduledExecutor ` 。` DelayedWorkQueue ` 的内部元素并不是按照放入的时间排序,而是会按照延迟的时间长短对任务进行排序,内部采用的是“堆”的数据结构,可以保证每次出队的任务都是当前队列中执行时间最靠前的。` DelayedWorkQueue ` 添加元素满了之后会自动扩容,增加原来容量的 50%,即永远不会阻塞,最大扩容可达 ` Integer.MAX_VALUE ` ,所以最多只能创建核心线程数的线程。
510510- ` ArrayBlockingQueue ` (有界阻塞队列):底层由数组实现,容量一旦创建,就不能修改。
@@ -655,7 +655,7 @@ CPU 密集型简单理解就是利用 CPU 计算能力的任务比如你在内
655655
656656这是一个常见的面试问题,本质其实还是在考察求职者对于线程池以及阻塞队列的掌握。
657657
658- 我们上面也提到了,不同的线程池会选用不同的阻塞队列作为任务队列,比如` FixedThreadPool ` 使用的是` LinkedBlockingQueue ` (无界队列) ,由于队列永远不会被放满,因此` FixedThreadPool ` 最多只能创建核心线程数的线程。
658+ 我们上面也提到了,不同的线程池会选用不同的阻塞队列作为任务队列,比如` FixedThreadPool ` 使用的是` LinkedBlockingQueue ` (有界队列),默认构造器初始的队列长度为 ` Integer.MAX_VALUE ` ,由于队列永远不会被放满,因此` FixedThreadPool ` 最多只能创建核心线程数的线程。
659659
660660假如我们需要实现一个优先级任务线程池的话,那可以考虑使用 ` PriorityBlockingQueue ` (优先级阻塞队列)作为任务队列(` ThreadPoolExecutor ` 的构造函数有一个 ` workQueue ` 参数可以传入任务队列)。
661661
0 commit comments