线程池的工做主要是控制运行的线程数量,处理过程当中将任务放入队列,而后在线程建立后启动这些任务,若是线程数量超过了最大数量,那么多余的线程要排队等候,等待其余线程处理完毕,再从队列中取出任务来执行。java
主要特色:线程复用
控制最大并发数
管理线程
小程序
java中的线程池是经过executor框架实现的,该框架中用到了Executor接口、Executors类、ThreadPoolExecutor类和ScheduledThreadPoolExecutor类。Executors和Executor的关系等同于从Collections与Collection和Arrays与Array,前者提供了许多辅助工具类能够很方便的使用。 缓存
线程池的有5种,其中最经常使用的有如下三种多线程
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
复制代码
主要特色:架构
定长线程池
,可控制线程最大并发数,超出的线程会在队列中等待它使用的LinkedBolickingQueue
Executors.newSingleThreadExecutor() 只有一个线程 适用于单个任务现行执行的场景并发
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
复制代码
主要特色:框架
一个单线程化
的线程池,他只会用惟一的工做线程来执行任务,保证全部任务按照指定顺序执行它使用的LinkedBlockingQueue
Executors.newCachedThreadPool() 动态扩大线程数,适用于执行不少短时间异步的小程序或负载比较轻的服务异步
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
复制代码
主要特色:ide
可缓存线程池
,若是线程池长度超过处理须要,可灵活回收空闲线程,若无可回收,则新建线程。以上三段代码可知,线程池的构造都是从一个方法而来: ThreadPoolExecutor
工具
由以上三段代码可知,在Exectors内部建立线程池ide时候,实际建立的都是一个ThreadPoolExecutor对象,只是对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;
}
复制代码
参数含义以下:
参数使用场景:
corePoolSize
时,建立新的线程运行这个任务corePoolSize
,那么把任务放入队列
中maximumPool
,那么还要建立非核心线程
运行这个任务饱和拒绝策略
来执行。keepAliveTime
,线程池会判断 若是当前运行线程数大于corePoolSize,则线程被销毁当队列满了并且线程数已经达到maximumPoolSize,接下来的线程会受到拒绝策略的管控 拒绝策略有四种:
该任务须要大量的运算,而且没有阻塞,CPU一直全速运行,CPU密集任务只有在真正的多核CPU上才可能经过多线程加速
CPU密集型任务配置尽量少的线程数量:CPU核数+1个线程的线程池
IO密集型任务线程并非一直在执行任务,则应配置尽量多的线程,如CPU核数*2
根据阿里巴巴编码规约,不容许使用Executors去建立,而是经过ThreadPoolExecutor的方式建立,这样让写的同窗更加明确线程池的运行规则,避免资源耗尽的风险。 executors各个方法的弊端: