转自《Java编程思想》
Executor在客户端和任务执行之间提供了一个简介层,与客户端执行任务不同,这个中介对象将执行任务。Executor允许你管理异步任务的执行,而无须显示地管理线程的生命周期,Executor在Java SE5/6中是启动任务的优选方法。
对shutdown方法的调用可以防止新任务被提交给这个Executor,当前线程将继续运行在shutdown被调用之前提交的所有任务,这个程序将在Executor中的所有任务完成之后尽快退出。
实例:
public class FixedThreadPool{
public static void main(Sstring[] args){
ExecutorService exec = Executors.newFixedThreadPool(5);
for(int i = 0 ; i < 5 ; i++){
exec.execute(new Liftoff());//实现了Runnable的类
}
exec.shutdown();
}
}
有了FixedThreadPool,你就可以一次性预先执行代价高昂的线程分配,因而也就可以限制线程的数量了,这可以节省时间,因为你不用为每个任务都固定的付出创建线程的开销。在时间驱动的系统中,需要线程的时间处理器,通过直接从池中获取线程,也可以如你所愿的尽快得到服务,你不会滥用可获得的资源,因为FixedThreadPool使用的Thread对象的数量是有限的。
注意,在任何线程池中,现有线程在可能的情况下,都会被自动复用。
尽管本书将使用CachedThreadpool,但是也应该考虑在产生线程的代码中使用FixedThreadPool。CachedThreadPool在程序执行过程中通常会创建与所需数量相同的线程,然后在它回收旧线程时停止创建新线程,因此它是合理的Executor的首选。只有当这种方式会引发问题时,你才需要切换到FixedThreadPool。
SingleThreadExecutor就像是线程数量为1的FixedThreadPool。这对于你希望在另一个线程中连续运行的任何事物来说,都是很有用的,例如监听进入套接字连接的任务。它对于希望在线程中运行的短任务也同样很方便,例如事件分发线程。
如果向SingleThreadExecutor提交了多个任务,那么这些任务将排队,每个任务都会在下一个任务开始之前运行结束,所有的任务将使用相同的线程。
例子:
public class SingleThreadExecutor{
public static void main(String[] args){
ExecutorService exec = Executors.newSingleThreadExecutor();
for(int i = 0; i < 5; i++){
exec.execute(new LiftOff());
}
shutdown();
}
}