Executor框架的两极调度模型
●HotSpot虚拟机将Java线程一对一映射为本地操作系统线程。
●在应用层,应用被分解为多个任务,并由Executor框架负责分配线程执行任务。
●在操作系统层,内核将这些线程映射到内核线程,并交由处理器。
Executor框架的结构
● 任务:任务需要实现Runnable接口或者Callable接口。
●任务的执行:任务执行机制的核心接口为Executor,ExecutorService接口继承了Executor接口,Executor框架有两个关键类实现了ExecutorService接口,分别为ThreadPoolExecutor和ScheduledThreadPoolExecutor。
●异步计算的结果:包括Future接口和Future接口的实现类FutureTask。
对上述接口和类的简介
●Executor接口是Executor框架的基础,它将任务的提交和执行分离开来。
●ThreadPoolExecutor是线程池的核心实现类,用来执行提交的任务。
●ScheduledThreadPoolExecutor是线程池的实现类,用来延迟提交任务的执行时间或者定期执行任务。
●Future接口及其实现类FutureTask表示异步计算的结果。
●实现了Runnable或Callable接口的实现类可被ThreadPoolExecutor或者ScheduledThreadPoolExecutor执行。
Executor框架的成员
Executor框架的主要成员有ThreadPoolExecutor、ScheduledThreadPoolExecutor、Future接口、Runnable接口、Callable接口、Executors。
-
1.ThreadPoolExecutor:Executors可以创建三种类型的ThreadPoolExecutor,分别为SingleThreadExecutor、FixedThreadPool、CachedThreadPool。
-
- ①.FixedThreadPool:该线程池里的线程数是固定的,它适用于需要限制当前线程数量的场景和负担比较重的服务器。
-
- ②.SingleThreadExecutor:该线程池适用于需要按顺序执行任务,且在任意时间点只有一个线程在执行任务的场景。
-
- ③CachedThreadPool:该线程池适用于执行很多短期异步任务,或者是负担较轻的服务器。
- 2.ScheduledThreadPoolExecutor:Executors可以创建两种类型的ScheduledThreadPoolExecutor,分别为ScheduledThreadPoolExecutor、SingleThreadScheduledExecutor。
-
- ①.ScheduledThreadPoolExecutor:适用于需要多个后台线程执行周期任务,且需要限制后台线程数量的场景。
-
- ②SingleThreadScheduledExecutor:适用于需要单个后台线程执行周期任务,且保证任务按顺序执行的场景。
- 3.Future接口:当调用ThreadPoolExecutor或者ScheduledThreadPoolExecutor的submit(……)方法时,会返回一个实现了Future接口的对象(即FutureTask对象)。
- 4.Runnable接口和Callable接口:他们之间的区别是Runnable接口不会返回结果,Callable接口可以返回结果,但需要和FutureTask配合使用。
线程池详解
1.FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads){
return new ThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
- ●FixedThreadPool是一种可重用、固定线程数的线程池。
- ●FixedThreadPool的corePoolSize和maximumPoolSize大小均为nThreads。
- ●FixedThreadPool的阻塞队列为LinkBlockingQueue,该队列为无界队列,故keepAliveTime、maximumPoolSize这两个参数无效。
- ●由于队列无界,也就不需要饱和策略,handler这个参数也就没必要存在了。
2.SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor(){
return new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
- ●SingleThreadExecutor的corePoolSize和maximumPoolSize均为1,其余参数和FixedThreadPool一样。
- ●SingleThreadExecutor只会创建单个线程执行任务。
- ●SingleThreadExecutor支持按顺序执行任务。
3.CachedThreadPool
public static ExecutorService newCachedThreadPool(){
return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.MILLISECONDS,new SynchronousQueue<Runnable>());
}
- ●CachedThreadPool的corePoolSize为0,maximumPoolSize可理解为无限大,故该线程池是无界的。
- ●CachedThreadPool的keepAliveTime为60,表示线程池中空闲线程的存活时间为60秒,超过60秒后,空闲线程将被终止。
- ●CachedThreadPool的阻塞队列是SynchronousQueue,该队列不存储元素,意味着每当新任务来临时,若线程池中没有空闲线程执行新任务,则会有新线程被创建出来执行任务。若新任务被提交的速度大于线程被执行完成的速度,就会不断有新线程产生,极端情况下会耗尽系统资源。
4.ScheduledThreadPoolExecutor
●ScheduledThreadPoolExecutor主要用来延迟执行任务,或者定期执行任务。
●ScheduledThreadPoolExecutor的任务队列为DelayQueue,是一个无界队列。
●ScheduledThreadPoolExecutor使用方法scheduledAtFixedRate()或者scheduledWithFixedDelay()提交任务时,会 向DelayQueue队列添加一个实现了RunnableScheduledFuture接口的ShceduledFutureTask。
- SchduledFutureTask的3个主要参数:
- 1.time:任务开始的时间
- 2.sequenceNumber:任务被添加到队列中的序号
- 3.period:任务执行的时间间隔。
●ScheduledThreadPoolExecutor的队列DelayQueue封装了一个PriorityQueue,它会根据time的大小对ShceduledFutureTask进行排序,若time相同则根据sequenceNumber排序。
●ScheduledThreadPoolExecutor执行任务的步骤如下
- 1.线程从队列中获取已经到期的任务。
- 2.执行任务后修改任务的time变量为下次要执行的时间。
- 3.把任务重新返回到任务队列中。