线程池工作流程
线程池常用的阻塞队列
| 参数 |
描述 |
| ArrayBlockingQueue |
一个由数组结构组成的有界阻塞队列。 |
| LinkedBlockingQueue |
一个由链表结构组成的有界阻塞队列。常用 |
| SynchronousQueue |
一个不存储元素的阻塞队列,即直接提交给线程不保持它们。常用 |
| PriorityBlockingQueue |
一个支持优先级排序的无界阻塞队列。 |
| DelayQueue |
一个使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素。 |
| LinkedTransferQueue |
一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。 |
| LinkedBlockingDeque |
一个由链表结构组成的双向阻塞队列。 |
线程池的拒绝策略
| 参数 |
描述 |
| AbortPolicy |
拒绝并抛出异常。默认的 |
| CallerRunsPolicy |
重试提交当前的任务,即再次调用运行该任务的execute()方法。 |
| DiscardOldestPolicy |
抛弃队列头部(最旧)的一个任务,并执行当前任务。 |
| DiscardPolicy |
抛弃当前任务。 |
Executors创建线程池OOM的原因
FixedThreadPool
1 2 3 4 5
| public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
|
SingleThreadPool
1 2 3 4 5 6 7
| public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
|
以上两种线程池都采用了LinkedBlockingQueue,而LinkedBlockingQueue在初始化时的最大长度是Integer.MAX_VALUE。
1 2 3 4
| public LinkedBlockingQueue() { this(Integer.MAX_VALUE); }
|
CachedThreadPool
1 2 3 4 5
| public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
|
这里线程池在初始化时,maximumPoolSize 参数用的是 Integer.MAX_VALUE,可能会创建大量的线程,导致发生OOM。