1:java中的线程池实现原理
2:上图中的任务队列(用于保存等待执行的任务的阻塞队列)介绍
(1)ArrayBlockingQueue:基于数组结构的有界阻塞队列,按照FIFO(先进先出)原则对元素进行排序。
(2)LinkedBlockingQueue:基于链表的阻塞队列,按照FIFO排序元素,吞吐量通常高于ArrayBlockingQueue.
静态工厂Executors.newFixedThreadPool()使用了它。
(3)SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用了移除操作,否则插入一直处于阻塞。吞吐量高于LinkedBlockingQueue。Executors.newCachedThreadPool使用了该队列。
(4)PriorityBlockingQueue:一个具有优先级的无限阻塞队列。
3:上图中饱和策略(RehectedExecutionHandler)介绍
(1)AbortPolicy:直接抛出异常。
(2)CallerRunsPolicy:只用调用者所在线程来运行任务。
(3)DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
(4)DiscardPolicy:不处理,丢弃了。
注意:也可以实现RejectedExecutionHandle接口自定义策略。比如:记录日志或持久化存储不能处理的任务。
4:向线程池提交任务
两种方法:
(1)execute():用于提交不需要返回值的的任务,无法判断任务是否被线程池执行成功。
(2)submit():用于提交需要返回值的任务。线程池返回一个future类型的对象。需要注意:调用future对象的get()方法会阻塞当前线程直到任务完成。而使用get(long timeout , TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候可能任务没有执行完。
5:关闭线程池
原理:遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程。
(1)shutdown():将线程池状态设置为SHUTDOWN状态,然后中断所有没有正在执行任务的线程。
(2)shutdownNow():将线程池状态设置为STOP,然后尝试停止所有的正在执行或暂停任务的线程。
注意:调用了2个方法中的任意一个,isShutdown方法就会返回true。当所有的任务都关闭以后,才表示线程池关闭成功,这时候调用isTerminaed方法会返回true.