public ThreadPoolExecutor(int corePoolSize, //线程池核心工作线程数量,比如newFixedThreadPool中可以自定义的线程数量就是这个参数 int maximumPoolSize, //线程池所有工作线程的数量,比如newFixedThreadPool中的最大工作线程就是核心线程数,newCachedThreadPool中的最大工作线程数是Integer.MAX_VALUE long keepAliveTime, //非核心线程存活的时间,当核心线程不够用的时候,创建出来的辅助工作线程在完成任务空闲多久后会被回收 TimeUnit unit, //上面一个参数的单位,分。秒等 BlockingQueue<Runnable> workQueue,//底层使用的阻塞队列数据结构,比如newFixedThreadPool底层使用LinkedBlockingQueue。工作队列,保存已提交但是未执行的任务 ThreadFactory threadFactory, //创建工作线程的工厂,保持默认即可 RejectedExecutionHandler handler) { //拒绝策略,即在所有工作线程数达到上限,底层阻塞队列也满了的时候采取的策略 if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.acc = System.getSecurityManager() == null ? null : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
上面四种都不使用,我们需要通过ThreadPoolExcutor自定义线程池,阿里巴巴java开发手册明确指出,不允许使用Excutors工具类进行线程池的创建,因为某些开发人员不了解底层运行规则,避免资源耗尽的危险
1:FixedThreadPool 和 SingleThreadPool: 允许的请求队列(底层实现是LinkedBlockingQueue)长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM
2:CachedThreadPool 和 ScheduledThreadPool 允许的创建线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM
new ThreadPoolExecutor.AbortPolicy(); //遇到线程池达到最大线程数,且队列已经满了,直接抛异常 ----默认
new ThreadPoolExecutor.DiscardOldestPolicy() //遇到线程池达到最大线程数且队列已经满了,则丢弃队列中最前面的任务,
new ThreadPoolExecutor.DiscardPolicy() //遇到线程池达到最大线程数且队列已经满了,丢弃当前任务,不给它加入队列中
new ThreadPoolExecutor.CallerRunsPolicy();//会将任务返回给提交者进行执行,比如让main线程直接执行run方法
1.避免大量线程的创建销毁带来的性能开销
2.避免大量线程之间因为相互抢占系统资源导致的阻塞状态
3.能够对线程进行简单的管理并提供定时执行,间隔执行等功能
在CPU密集型下,选用cpu核心数+1作为最大线程池工作线程数量,减少cpu切换任务带来的开销
在IO密集型下,尽可能多的加大工作线程数量,一般为cpu核心数*2
原文:https://www.cnblogs.com/williamGod/p/14882244.html