Executor框架、线程池及其生命周期

Java类库中,任务执行的主要抽象不是Thread,而是Executor。Executor框架具有以下几个特点:

  • 异步任务执行框架
  • 基于生产者-消费者模式
  • 将任务的提交过程与执行过程解耦,用runnable表示任务
  • 采用不同的Executor实现即可改变服务器的行为,简化了代码修改的难度
  • 支持生命周期管理、统计信息收集、应用程序管理机制和性能监视等机制。
 /* @since 1.5
 * @author Doug Lea
 */
public interface Executor {

    /**
     * Executes the given command at some time in the future.  The command
     * may execute in a new thread, in a pooled thread, or in the calling
     * thread, at the discretion of the <tt>Executor</tt> implementation.
     *
     * @param command the runnable task
     * @throws RejectedExecutionException if this task cannot be
     * accepted for execution.
     * @throws NullPointerException if command is null
     */
    void execute(Runnable command);
}

1、几种Executor实现方式举例

package com.wenc.concurrency;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class TaskExecutionWebServer {

	private static final int THREAD_NUMBER = 100;
	private static final Executor exec = Executors.newFixedThreadPool(THREAD_NUMBER);
	
	public static void main(String[] args) throws IOException {
		ServerSocket socket = new ServerSocket(80);
		while(true){
			final Socket connection = socket.accept();
			Runnable task = new Runnable(){
				@Override
				public void run() {
					handleRequest(connection);
				}
			};
			exec.execute(task);
		}
	}
}
基于线程池的web服务器


package com.wenc.concurrency;

import java.util.concurrent.Executor;

public class ThreadPerTaskExecutor implements Executor{
	@Override
	public void execute(Runnable command) {
		new Thread(command).start();
	}
}
每个请求启动一个新线程

package com.wenc.concurrency;

import java.util.concurrent.Executor;

public class WithinThreadExecutor implements Executor{
	@Override
	public void execute(Runnable command) {
		command.run();
	}
}
在当前线程中执行(单线程)

2、线程池

指管理一组同构工作线程的资源池。线程池与工作队列密切相关,其中在工作队列中保存了所有等待执行的任务。工作者线程的任务:从工作队列中获取一个任务,执行任务,然后返回线程池并等待下一个任务。
与上面的ThreadPerTaskExecutor相比,线程池有以下几个优点:
  • 重用线程,免去线程创建和销毁的开销
  • 无需创建线程,响应速度更快
  • 通过调整线程池的大小,可以创建足够的线程以充分利用处理器资源,同时可以防止多线程相互竞争资源而使应用程序耗尽内存或失败,提高稳定性。
类库提供了常用的线程池实现:
  • newFixedThreadPool,固定长度,每提交一个任务就创建一个线程,直到达到线程池最大数量。如果某个线程异常结束,那么线程池会补充一个新的线程。
  • newCachedThreadPool,规模无限制,空闲回收、需要则新增线程,可缓存。
  • newSingleThreadExecutor,大小为1,即,单线程。如果该线程异常结束,则会创建另一个线程来替代,可确保工作任务串行执行。
  • newScheduledThreadPool,固定长度,以延迟或定时方式执行任务,类似Timer。

3、生命周期

Executor扩展了ExecutorService接口,添加了一些用于声明周期管理的方法,
public interface ExecutorService extends Executor {

    /**
     * Initiates an orderly shutdown in which previously submitted
     * tasks are executed, but no new tasks will be accepted.
     * Invocation has no additional effect if already shut down.
     *
     * @throws SecurityException if a security manager exists and
     *         shutting down this ExecutorService may manipulate
     *         threads that the caller is not permitted to modify
     *         because it does not hold {@link
     *         java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
     *         or the security manager's <tt>checkAccess</tt> method
     *         denies access.
     */
    void shutdown();

    /**
     * Attempts to stop all actively executing tasks, halts the
     * processing of waiting tasks, and returns a list of the tasks that were
     * awaiting execution.
     *
     * <p>There are no guarantees beyond best-effort attempts to stop
     * processing actively executing tasks.  For example, typical
     * implementations will cancel via {@link Thread#interrupt}, so any
     * task that fails to respond to interrupts may never terminate.
     *
     * @return list of tasks that never commenced execution
     * @throws SecurityException if a security manager exists and
     *         shutting down this ExecutorService may manipulate
     *         threads that the caller is not permitted to modify
     *         because it does not hold {@link
     *         java.lang.RuntimePermission}<tt>("modifyThread")</tt>,
     *         or the security manager's <tt>checkAccess</tt> method
     *         denies access.
     */
    List<Runnable> shutdownNow();

    /**
     * Returns <tt>true</tt> if this executor has been shut down.
     *
     * @return <tt>true</tt> if this executor has been shut down
     */
    boolean isShutdown();

    /**
     * Returns <tt>true</tt> if all tasks have completed following shut down.
     * Note that <tt>isTerminated</tt> is never <tt>true</tt> unless
     * either <tt>shutdown</tt> or <tt>shutdownNow</tt> was called first.
     *
     * @return <tt>true</tt> if all tasks have completed following shut down
     */
    boolean isTerminated();

    /**
     * Blocks until all tasks have completed execution after a shutdown
     * request, or the timeout occurs, or the current thread is
     * interrupted, whichever happens first.
     *
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return <tt>true</tt> if this executor terminated and
     *         <tt>false</tt> if the timeout elapsed before termination
     * @throws InterruptedException if interrupted while waiting
     */
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;

以下是一个使用ExecutorServie实现的支持关闭操作的web服务器:
package com.wenc.concurrency;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;

/**
 * 支持关闭操作的web服务器
 * @author wenc
 *
 */
public class LifeCycleWebServer {
	private final ExecutorService exec = Executors.newFixedThreadPool(10);
	
	public void start() throws IOException{
		ServerSocket socket = new ServerSocket(80);
		while(!exec.isShutdown()){
			try{
				final Socket conn = socket.accept();
				exec.execute(new Runnable() {
					@Override
					public void run() {
						handleRequest(conn);
					}
				});
			}catch(RejectedExecutionException e){
				if(!exec.isShutdown())
					System.out.println("task submission rejected" + e);
			}
		}
	}
	
	public void stop(){
		exec.shutdown();
	}
	
	void handleRequest(Socket conn){
		Request req = readRequest(conn);
		if(isShutdownRequest(req))
			stop();
		else
			dispatchRequest(conn);
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值