线程池的基础概念
core,maxPoolSize,keepalive
执行任务时
1. 如果线程池中线程数量 < core,新建一个线程执行任务;
2. 如果线程池中线程数量 >= core ,则将任务放入任务队列
3. 如果线程池中线程数量 >= core 且 < maxPoolSize,则创建新的线程;
4. 如果线程池中线程数量 > core ,当线程空闲时间超过了keepalive时,则会销毁线程;由此可见线程
池的队列如果是无界队列,那么设置线程池最大数量是无效的;
自带线程池的各种坑
1. Executors.newFixedThreadPool(10);
固定大小的线程池:
它的实现new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS,new
LinkedBlockingQueue());
初始化一个指定线程数的线程池,其中corePoolSize == maximumPoolSize,使用
LinkedBlockingQuene作为阻塞队列,当线程池没有可执行任务时,也不会释放线程。
由于LinkedBlockingQuene的特性,这个队列是无界的,若消费不过来,会导致内存被任务队列占
满,最终oom;
2. Executors.newCachedThreadPool();
缓存线程池:
它的实现new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new
SynchronousQueue());
初始化一个可以缓存线程的线程池,默认缓存60s,线程池的线程数可达到Integer.MAX_VALUE,
即2147483647,内部使用SynchronousQueue作为阻塞队列;和newFixedThreadPool创建的线
程池不同,newCachedThreadPool在没有任务执行时,当线程的空闲时间超过keepAliveTime,
会自动释放线程资源,当提交新任务时,如果没有空闲线程,则创建新线程执行任务,会导致一定
的系统开销,因为线程池的最大值了Integer.MAX_VALUE,会导致无限创建线程;所以,使用该线
程池时,一定要注意控制并发的任务数,否则创建大量的线程会导致严重的性能问题;
3. Executors.newSingleThreadExecutor()
单线程线程池:
同newFixedThreadPool线程池一样,队列用的是LinkedBlockingQueue无界队列,可以无限的往
里面添加任务,直到内存溢出;