如下为我的的学习和总结,若是只是为了了解线程池,能够谷歌到大量优秀的文章.这里只是为了记录个人学习思路,参考的其余人的博客.,有些概括不正确之处望斧正 我会不断概括总结新看到的文章来丰富细节java
除了用线程池代码看起来比较高大上这个理由外,先说说用线程池和不用线程池相比都有什么好处吧 我就用大白话解释了,总比复制粘贴死记硬背好些吧......数组
会用线程池不就得了?为啥还要学那些乱七八糟的参数?贼复杂还很差背. 业务驱动技术,咱们在实际业务中可能须要到用到拥有不一样特性的线程池.废话很少说,先来DIY吧学习
数组结构
的有界阻塞队列,此队列按 FIFO
(先进先出)原则对元素进行排序。 LinkedBlockingQueue:一个基于链表结构
的阻塞队列,此队列按FIFO
(先进先出) 排序元素,吞吐量一般要高于ArrayBlockingQueue
。静态工厂方法Executors.newFixedThreadPool()
使用了这个队列。 SynchronousQueue:一个不存储元素的阻塞队列
。每一个插入操做必须等到另外一个线程调用移除操做,不然插入操做一直处于阻塞状态
,吞吐量一般要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool
使用了这个队列。 SynchronousQueue没有容纳元素的能力,即它的isEmpty()方法老是返回true,可是给人的感受却像是只能容纳一个元素。它模拟的功能相似于生活中一手交钱一手交货这种情形 PriorityBlockingQueue:一个具备优先级的无限阻塞队列。队列满了
,而且已建立的线程数小于最大线程数
,则线程池会再建立新的线程执行任务。值得注意的是若是使用了无界的任务队列这个参数就没什么效果。队列和线程池都满了
,说明线程池处于饱和状态,那么必须采起一种策略处理提交的新任务。这个策略默认状况下是AbortPolicy,表示没法处理新任务时抛出异常。如下是JDK1.5提供的四种策略。 AbortPolicy(舍弃-抛出异常):直接抛出异常。 CallerRunsPolicy(调用者执行):只用调用者所在线程来运行任务。 DiscardOldestPolicy(丢弃最旧的):丢弃队列里最近的一个任务,并执行当前任务。 DiscardPolicy(丢弃):不处理,丢弃掉。 固然也能够根据应用场景须要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。参数比较多,但咱们要抓住重点去理解而不是死记硬背.线程池长啥样?简单描述就是个带着个阻塞队列的池子.固然它不是"死"的,它有本身解决特殊问题的各类的策略(饱和策略)线程
new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler);
rest
有两种方式提交: execute 和 submit日志
shutdown或shutdownNow方法来关闭线程池 原理是遍历线程池中的工做线程,而后逐个调用线程的interrupt
方法来中断线程,因此没法响应中断的任务可能永远没法终止。 shutdownNow首先将线程池的状态设置成STOP
,而后尝试中止全部的正在执行或暂停任务的线程,并返回等待执行任务的列表 shutdown只是将线程池的状态设置成SHUTDOWN
状态,而后中断全部没有正在执行任务的线程。code
线程池的处理流程以下:排序
首先线程池判断基本线程池
是否已满?没满,建立一个工做线程来执行任务。满了,则进入下个流程。 其次线程池判断工做队列
是否已满?没满,则将新提交的任务存储在工做队列里。满了,则进入下个流程。 最后线程池判断整个线程池
是否已满?没满,则建立一个新的工做线程来执行任务,满了,则交给饱和策略
来处理这个任务。接口
经过线程池提供的参数进行监控。线程池里有一些属性在监控线程池的时候可使用 taskCount:线程池须要执行的任务数量。 completedTaskCount:线程池在运行过程当中已完成的任务数量。小于或等于taskCount。 largestPoolSize:线程池曾经建立过的最大线程数量。经过这个数据能够知道线程池是否满过。如等于线程池的最大大小,则表示线程池曾经满了。 getPoolSize:线程池的线程数量。若是线程池不销毁的话,池里的线程不会自动销毁,因此这个大小只增不+ getActiveCount:获取活动的线程数。生命周期