1.Runable、Callable、Future、Futuretask
(1)、Runable 实现Runable接口,覆写run方法,创建线程。
(2)、Callable 实现Callable接口,覆写call方法,创建一个带返回值的线程。
(3)、Future是一个异步计算的控制接口,可以获取返回值和取消执行的任务
(4)、FutureTask是Future的一个实现,主要用于做线程的包装。
2.java的线程池
小白的问题:线程怎么能保持住状态而被复用?
Executor Executors 和ExecutorService关系:
所有的实现都是依赖于ThreadPoolExecutor,我们最常用的是通过工具类Exectors生成相关的线程池:
以上所有的实现都是基于ThreadPoolExecutor实现的。
在分析源码之前我们需要明确几个概念:
ThreadPoolExecutor中有两个线程池,CorePool(核心线程池)和MaxPool(最大线程池)
当线程提交的原则
1.线程优先向CorePool中提交
2.在Corepool满了之后,线程被提交到任务队列,等待线程池空闲。
3.在任务队列满了之后,任务被提交到maxPool中,如果MaxPool满了之后执行task拒绝策略。
我们常用的几种线程池:
FixedThreadPool:创建固定大小的线程池(核心线程),同时提供一个无界的任务队列,当任务过多时会将任务提交到队列中。
SingleThreadPool:创建一个只有一个线程的线程池,同时使用无界队列做任务队列,不可以扩容,但是Fix(1)可以扩容。
CachedThreadPool:核心线程池大小为0,使用SynchronousQueue做任务队列,当提交任务过多而消费线程过小时会无限创建线程,线程池超时时间为60s
这里面其实有很多细节,首先看几个问题:
1.线程池中的线程是什么时候创建的?
2.线程池中的线程到底响应中断吗?线程怎么能停下来?
3.submit和execute有什么区别?
4.shutdown和shutdownNow有什么区别?怎么实现?
5.线程池中的线程都运行完了,为什么线程池不退出?
6.线程池的状态都有哪些?都是怎么转换的?
7.线程池的等待超时策略是什么?
ThreadPoolExecutor 源码分析
3.ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor是一个定时调度的任务调度线程池,整体实现基于延时。
线程池中存储的调度对象为:ScheduledFutureTask
带着问题看代码:
1.ScheduledThreadPoolExecutor是怎样实现延迟调度的?
2.ScheduledThreadPoolExecutor内是怎么实现任务排序的?
3.如何做到任务循环调度?
4.任务队列怎么做同步?新创建的任务如何能快速被调度到?
5.任务一定是能及时被调度的吗?线程阻塞了怎么办?