1. 线程池作用
销毁和创建线程的代价大,频繁地销毁和创建线程会降低系统性能并且占用CPU,而CPU的主要功能是负责解决业务问题,所以线程池能帮助系统更好地专注于业务而不是辅助功能上。
2. Executors
2.1 作用
创建线程池,实际是调用了包装好的ThreadPoolExecutor
2.2 线程池的种类
2.2.1 newFixedThreadPool
创建一个固定数量的线程池
123456 public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,//最小和最大数量都是同一个数:固定数量0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()//阻塞队列:线程排队);}
2.2.2 newSingleThreadExecutor
创建只有一个线程的线程池
123456 public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,//只有一个线程的线程池0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}
2.2.3 newCachedThreadPool
线程的数量是能弹性伸缩的线程池,即线程数量会随着需求而变化,不是固定着数量
123456 public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,//弹性范围60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>()//不保存内容的队列);}
2.2.4 newScheduledThreadPool
具有调度功能的线程池,会在给定延迟时间后执行命令或者定期执行
1234 public ScheduledThreadPoolExecutor(int corePoolSize) {super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,new DelayedWorkQueue());}
3. ThreadPoolExecutor分析
ThreadPoolExecutor是Executors创建线程池的基础,通过ThreadPoolExecutor的分析能更好地理解线程池
3.1 构造函数
|
|
3.2 回调接口
beforeExecute
afterExecute
terminated
3.3 workQueue队列
用来保存等待执行的任务,是一个阻塞队列,有以下几种:
① ArrayBlockingQueue:基于数组结构的有界阻塞队列(FIFO先进先出)
② LinekedBlocingQueue:基于链表结构的有界阻塞队列(FIFO先进先出);newFixedThreadPool使用此队列
③ SynchronousQueue:不存储元素的阻塞队列;newCachedThreadPool使用此队列,当有线程写入数据以及有线程读取数据时(同时操作),才能发挥作用,仅仅是写入没有读取等操作是无效的,因为SynchronousQueue不保存数据。
④ PriorityBlockingQueue:具有优先级的无限阻塞队列
吞吐量排行:SynchronousQueue > LinkedBlockingQueue > ArrayBlockingQueue
3.4 RejectedExecutionHandler拒绝策略
当队列已满时,而线程池又处于状态,此时其他任务就无法执行,通过拒绝策略来对这一部分任务进行处理,有以下几种:
① AbortPolicy:直接抛出异常
② CallerRunsPolicy:用调用者所在的线程来执行任务
③ DiscardOldestPolicy:丢弃队列中最老(队列头)的任务
④ DiscardPolicy:不处理,直接丢弃
3.5 执行任务:submit()和execute()的区别
- submit():返回一个future,通过future来判断任务是否执行成功
get():获取返回值,通过返回值判断是否执行成功;会阻塞方法直到任务完成
get(long timeout, TimeUnit unit):阻塞一段时间后返回,无论是否执行成功- execute():无法判断任务是否执行成功