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

来源:互联网 发布:软件测试项目描述 编辑:程序博客网 时间:2024/05/21 07:57

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(){@Overridepublic void run() {handleRequest(connection);}};exec.execute(task);}}}
基于线程池的web服务器


package com.wenc.concurrency;import java.util.concurrent.Executor;public class ThreadPerTaskExecutor implements Executor{@Overridepublic void execute(Runnable command) {new Thread(command).start();}}
每个请求启动一个新线程

package com.wenc.concurrency;import java.util.concurrent.Executor;public class WithinThreadExecutor implements Executor{@Overridepublic 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() {@Overridepublic 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();elsedispatchRequest(conn);}}



原创粉丝点击