在java的concurrent.Executors主要提供两种线程池:无固定线程数但有限制任务队列的cachedThreadPool与有固定线程数但无任务队列限制的fixedThreadPool,这两种线程池是在小任务里面使用是正常的,但是一旦任务增大或者代码逻辑有问题,很容易导致OOM。因此《阿里巴巴Java指导手册》里面强制要求工程师不得使用这两种线程池,而是使用自己定义的ThreadPoolExecutor。
1 /** 2 * 线程池构造的测试 3 */ 4 public class ThreadPoolTest { 5 public static void main(String[] args) { 6 /* 7 return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 8 60L, TimeUnit.SECONDS, 9 new SynchronousQueue<Runnable>()); 10 */ 11 ThreadPoolExecutor cachedThreadPool = (ThreadPoolExecutor) Executors.newCachedThreadPool(); 12 /* 13 return new ThreadPoolExecutor(nThreads, nThreads, 14 0L, TimeUnit.MILLISECONDS, 15 new LinkedBlockingQueue<Runnable>()); 16 */ 17 ThreadPoolExecutor fixedThreadPool= (ThreadPoolExecutor) Executors.newFixedThreadPool(1); 18 19 /* 20 构造同时约束线程数与任务队列的线程池 21 */ 22 final int CORE_THREAD_COUNT=1; 23 final int MAX_THREAD_COUNT=10; 24 final long KEEP_ALIVE_TIME = 60L; 25 final TimeUnit ALIVE_TIME_UNIT = TimeUnit.SECONDS; 26 final BlockingQueue<Runnable> queue = new SynchronousQueue<>(); 27 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(CORE_THREAD_COUNT, MAX_THREAD_COUNT, KEEP_ALIVE_TIME, ALIVE_TIME_UNIT, queue); 28 } 29 30 }
从代码可以看得出来,cachedThreadPool的maximumPoolSize为Integer.MAX_VALUE,而fixedThreadPool的任务队列为无限制的LinkedBlockingQueue,这两种在任务量增大或者循环提交任务时,都很容易导致OOM。