java中的线程池
java线程池运用场景最多的并发框架,几乎所有需要异步或者并发执行的都需要线程池,好处
1) 降低资源消耗
2) 提高响应速度
3) 提高线程的可管理性(统一分配调度)
线程池的实现原理:
1) 线程池判断核心线程是否都在工作,如果不是,则创建一个新的工作线程来执行任务,否则进入下一个
2) 线程池判断工作队列是否已经满,如果工作队列没有满,就将新提交的任务存储在工作队列中,如果工作队列满了,就进入下一个流程
3) 线程池判断线程是否都处于工作状态.如果没有,就创建一个新的工作线程来执行任务.如果已经满了,则交给饱和策略来处理这个任务.
runnableTaskQueue(任务队列) 1 ArrayBlockingQueue:是一个基于数组结构的有界队列,此队列按照FIFO(先进先出)原则对元素排序 2 LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按照FIFO排序元素,吞吐量要高于ArrayBlockingQueue 3 SynchronousQueue: 一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常较高 4 PriorityBlockingQueue: 一个具有优先级无限阻塞队列. RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,必须采取一种策略处理提交的新任务.这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常. 1 AbortPolicy: 直接抛出异常 2 CallerRunsPolicy: 只用调用者所在的线程来运行任务 3 DiscardOldestPolicy: 丢弃队列里最近的一个任务,并执行当前的任务 4 DiscardPolicy: 不处理,丢弃掉 线程池提交任务: execute() 和 submit() 无返回值 返回Future对象
关闭线程池
可以通过shutDown()和shutDownNow()来关闭线程池,原理是遍历线程池中的每个线程,然后逐个调用interrupt方法来中断线程,所以无法响应中断的线程可能永远无法停止.
shutDownNow首先将线程池中状态设置为stop,然后停止尝试所有的正在执行或暂停的任务线程,并返回等待执行的任务列表,shutDown只是将线程池的状态置成shutdown状态,然后中断所有没有正在执行任务的线程.
合理配置线程池
cpu密集型,应该尽量配置尽可能小的线程 N+1个线程的线程池
I/O密集型,应该尽量配置尽可能多的线程 2*N
优先级不同的任务可以使用优先级队列来处理.
建议使用有界队列.