Java线程池
最核心代码:ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize, //核心线程数
int maximumPoolSize, //最大线程数:核心线程数+非核心线程数
long keepAliveTime, //空闲线程多久被回收
TimeUnit unit, //时间单位
BlockingQueue<Runnable> workQueue, //阻塞队列,用来存放等待执行的任务
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;
}
- workQueue :任务队列
- SynchronousQueue:该队列不存储任务,直接提交给线程
- ArrayBlockingQueue:基于数组的有界队列,先进先出原则
- LinkedBlockingQueue:基于链表的有界队列,先进先出原则
- handler:饱和策略
- AbortPolicy:丢弃任务并抛出RejectedExecutionException异常
- DiscardPolicy:丢弃任务,但不抛出异常
- DiscardOldestPolicy:丢弃队列最前面的任务,并执行新传入的任务
- CallerRunsPolicy:线程池的所在的线程去执行任务
以上是线程池最核心内容
接下来我们看看Executors中的几个创建线程池的方法方法,就是基于核心new ThreadPoolExecutor创建线程池
单线程线程池:newSingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
核心线程1,最大线程1(无非核心线程),空闲线程失效时间为0,队列的最大长度为Integer.MAX_VALUE(0x7fffffff)
缺点:队列容量过大,可能会堆积大量的任务,从而造成OOM
固定数量线程池:newFixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);
}
核心线程nThreads,最大线程nThreads(无非核心线程),空闲线程失效时间为0,队列的最大长度为Integer.MAX_VALUE(0x7fffffff)
缺点:队列容量过大,可能会堆积大量的任务,从而造成OOM
缓存线程池:newCachedThreadPool
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
核心线程0,最大线程为Integer.MAX_VALUE(0x7fffffff全是非核心线程),空闲线程失效时间为60秒,队列为SynchronousQueue,表示不存储任务,直接让线程去执行
缺点:最大线程数过大,可能会创建大量线程,从而造成OOM
总结
阿里开发文档不推荐使用Executors来创建线程,会有内存溢出的可能性。 开发者通过ThreadPoolExecutor创建,自定义线程池的参数,这样可以避免一些已知的问题。
线程数配置推荐
CPU密集型:核心线程数 = CPU核数 + 1
IO密集型:核心线程数 = CPU核数 * 2

浙公网安备 33010602011771号