Executors的四种连接池

文章摘抄于《Java并发实战》121页

线程池概念

	正如名称中所称的那样,线程池管理一个工作者线程的同构池(homongeneous pool)。线程池是与工作对列(wore queue)紧密绑定的。所谓工作队列,其作用是持有所有等待执行的任务。工作者线程从工作队列中获取下一个任务,执行它,然后回去继续等待另一个线程。
	在线程池中执行任务线程,这种方法有很多“每任务每线程”无法比拟的优势。重用存在的线程,而不是创建新的线程。这可以在处理多请求时抵消线程创建、消亡产生的开销。另一项额外的好处是,在请求到达时,工作者线程通常已经存在,用于创建线程的等待时间不会延迟任务的执,因此提高了响应度。通过适当的调整线程池的大小,你可以得到足够多的线程以保持处理器忙碌,同时还可以防止过多的线程相互竞争资源,导致应用程序耗尽内存或者失败。

Executor接口代码

public interface Executor{
	void execute(Runnable command);
}

四种线程池

	类库提供了一个灵活的线程池实现和一些有用的预设配置,你可以通过调用Executors中的某种静态工厂来创建一个线程池:
	(1)newFixedThreadPool创建了定长的线程池,每当提交一个任务就创建一个线程,直到达到池的最大长度,这时线程池会保持长度不再变化(如果一个线程由于非预期的Exception而结束,线程池会补充一个新的线程)。
	(2)newCachedThreadPool创建一个可缓存的线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活地回收空闲地线程。
	(3)newSingleThreadExecutor创建一个单线程化地executor,它只创建唯一的工作者线程来执行任务,如果这个线程异常结束,会有另一个取代它。executor会保证任务依照任务队列所规定的顺序执行。
	(4)newScheduleThreadPool拆概念一个定长的线程池,而且支持定时以及周期性的任务执行,类似于Timer;

Executor的生命周期

	Executor实现通常只是为了执行任务而创建线程,但是JVM会在所有(非后台的,nondaemin)线程全部终止后才退出。因此,如果无法正确关闭Executor,将会组织JVM的结束。
	因为Executor是异步地执行任务,所以在任何时间里,所有之前提交的任务的状态都不能立即可见。这些任务中,有可能已经完成,有可能正在运行。其他的还可能在队列中等待执行。关闭应用程序时,程序会出现很多种情况:从最平缓的关闭(已经启动的任务全部完成而且没有再接到任何新的工作)到最唐突的关闭(拔掉机房的电源),以及介于这两种极端情况之间的各种可能。既然Executor是为应用程序提供的,他们理应可以关闭,无论是平缓的还是唐突的。另外,关闭操作还会影响到记录应用程序任务状态的反馈信息。
	为了解决这个执行服务的生命周期问题,ExecutorService接口扩展了Executor,并且添加了一些用于生命周期管理的方法(同时还有一些用于任务提交的便利方法)。如下:
public interface ExecutorServiece extends Executor{
	void shutdown();
	List<Runnable> shutdownNow();
	boolean isShutdown();
	boolean isTerminated();
	boolean awaitTermination(long timeout,TimeUnit unit) throws IterruptedException;
}
	ExecutorService暗示了生命周期有3种状态:运行(running)、关闭(shutting down)和终止(terminated)。ExecutorService最初后的初始状态是运行状态。shutdown方法会启动一个平缓的关闭过程。停止接受新的任务,同时等待已经提交的任务完成---包括尚未开始执行的任务。shutdownNow方法会启动一个强制的关闭过程,尝试取消所有运行中的任务和排在队列中尚未开始的任务。
	在关闭后提交到ExecutorService中的任务,会被拒绝执行处理器(rejected execution handler)处理。拒绝执行处理器(拒绝执行处理器是ExecutorService的一种实现。ThreadPoolExecutor提供的,ExecutorService接口中的方法并不提供拒绝执行处理器。)可能只是简单的拒绝任务,也可能会引起execute抛出一个未检查RejectdExecutionException。一旦所有的任务全部完成后,ExecutorService会转入终止状态。你可以调用awaitTermination等待ExecutorService到达终止状态,也可以轮询检查isTerminated判断ExecutorService是否已经终止。通常shutdown会紧随awaiTermination之后,这样可以产生同步地关闭ExetorService的效果。
class LifecycleWebServer{
	private final ExecutorService exec=...;
	
	public void start() throws IOException{
		ServiceSocket socket=new ServerSocket(80);
		while(!exec.isShtudown)){
			try{
				final Socket conn=socket.accept();
				exec.execute(new Runnable(){
					public void run(){handleRequest(conn);}
				};
			}catch(RejectedExecutionException e){
				log("task sunmission rejected",e);
			}
		}
	}
	public void stop(){exec.shutdown();} 
	void handlerRequest(Socket connection){
		Request req=readReuest(connection);
		if(isShutdownRequest(req))
			stop();
		else
			dispatchRequest(req);
	}
}

你可能感兴趣的:(java)