Java的线程既是工作单元,也是执行机制。从JDK 5开始,把工作单元与执行机制分离开来。工作单元包括Runnable
和Callable
,而执行机制由Executor
框架提供。
Executor框架
Executor框架的两级调度模型
对于Sun JDK来说,它的Windows版和Linux版都是使用一对一的线程模型实现的,一条Java线程就映射到一条轻量级进程(LWP)中。
参见:Java与线程
Executor框架的两级调度模型可以描述为:在上层,Java多线程程序通常把应用分解为若干个任务,然后使用用户级的调度器(Executor框架)将这些任务映射为固定数量的线程;在底层,操作系统内核将这些线程映射到硬件处理器上。
Executor框架的结构
Executor框架主要由3部分组成:
任务
被执行的任务需要实现的接口:
Runnable
或者Callable
任务的执行
包括任务执行机制的核心接口
Executor
,以及继承自Executor
的ExecutorService
接口。Executor框架有两个关键类实现了
ExecutorService
接口:ThreadPoolExecutor
和ScheduledThreadPoolExecutor
。异步计算的结果
包括接口
Future
和其实现类FutureTask
。
Executor框架的类与接口
Executor框架的使用示意图
ThreadPoolExecutor
ThreadPoolExecutor
通常使用Executors
工厂类来创建,可以创建以下3种类型:
FixedThreadPool
Executors.newFixedThreadPool(int)
适用于为了满足资源管理的需求,而需要限制当前线程数量的应用场景,适用于负载比较重的服务器。工作队列
workQueue
使用的是LinkedBlockingQueue
,容量为Integer.MAX_VALUE
。SingleThreadExecutor
Executors.newSingleThreadExecutor()
适用于需要保证顺序地执行各个任务;并且在任意时间点,不会有多个线程是活动的应用场景。工作队列
workQueue
使用的是LinkedBlockingQueue
。容量为Integer.MAX_VALUE
。CachedThreadPool
Executors.newCachedThreadPool()
适用于执行很多的短期异步任务的小程序,或者是负载较轻的服务器。corePoolSize
为0,maximumPoolSize
被设置为Integer.MAX_VALUE
,即无界的。作队列
workQueue
使用的是SynchronousQueue
。
FixedThreadPool和SingleThreadExecutor使用无界队列LinkedBlockingQueue
作为线程池的工作队列。CachedThreadPool使用没有容量的SynchronousQueue
作为线程池的工作队列,但是CachedThreadPool的maximumPoolSize
是无界的。这意味着,如果主线程提交任务的速度高于maximumPool
中处理任务的速度时,CachedThreadPool会不断创建线程。极端情况下,CachedThreadPool会因为创建过多线程而耗尽CPU和内存资源。
ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor
可以在给定的延迟后运行命令或者定期执行命令,使用Executors
工厂类来创建,由2种类型:
ScheduledThreadPoolExecutor
包含若干个线程的
ScheduledThreadPoolExecutor
。SingleScheduledThreadPoolExecutor
只包含一个线程的
ScheduledThreadPoolExecutor
。
ScheduledThreadPoolExecutor
会把调度任务(ScheduledFutureTask)放到DelayQueue
中。
FutureTask
Future
接口和其实现类FutureTask
代表了异步计算的结果。
FutureTask实现了两个接口,Runnable和Future,所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
|
|
FutureTask
除了实现了Future
接口外,还实现了Runnable
接口,因此FutureTask
可以交给Executor
执行,也可以由调用线程直接执行(FutureTask.run()
)。
FutureTask的状态
FutureTask可以处于以下3种状态:
未启动
FutureTask.run()
被创建但是还没有被执行之前,FutureTask处于未启动状态。已启动
FutureTask.run()
方法被执行的过程中,FutureTask处于已启动状态。完成
FutureTask.run()
执行完后正常结束,或被取消(Future.cancel(...)
),或执行时抛出异常而结束,FutureTask处于完成状态。
|
|