并发编程八----Executor框架的作用

Executor是一个多线程管理框架,创建线程的方式有三种Thread、Runnable、Callable。但是如果用这三种方式创建线程则存在线程的生命周期管理困难,无限创建线程的话还会存在资源消耗(内存消耗高)、线程生命周期的开销过高(cpu计算资源的消耗)、系统稳定性问题(不同系统创建线程的数量限制不同包括JVM的启动参数、Thread构造函数请求的栈大小、底层操作系统对线程数量的限制)。

Executor是一个基于生产者和消费者模式的接口。主要做了以下几件事:

1、为灵活和强大的异步任务执行框架提供了基础功能,

2、提供了对生命周期的支

3、统计信息收集、应用程序管理机制和性能监视等机制,其配置是一次性的一般在部署阶段完成。

Executor是为应用程序提供服务的,并会将关闭操作中受影响的任务的状态反馈给应用程序。并且也是可以关闭的。

Executor采用的是两阶段处理方式:将任务的提交和执行解耦开来,通过调用Executors中的静态工厂方法创建线程池:定长线程池(newFixThreadPool)、缓存线程池(newCachedThreadPool)、定时线程池(newScheduledThreadPool)、单一线程池(newSingleThreadPool)。

为了解决线程生命周期的管理问题,ExecutorService接口扩展了Executor,添加了管理生命周期的方法:

public interface ExecutorService extends Executor{
    void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedExecption;
}

ExecutorService的生命周期有三种状态:1、运行 2、关闭 3、已终止,分别对应着创建时的状态、shutdown和shutdownNow()的关闭状态和awaitTermination的状态。

了解了ExecutorService是对Executor框架的扩展以及其作用以后再接着看Executor中的任务,在Executor框架中任务的生命周期分为四种:创建、提交、开始、完成,并用Future来表示任务的生命周期,并提供相关方法判断任务是否完成和取消。

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;

     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     * @throws TimeoutException if the wait timed out
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

在get方法中存在状态依赖,如果任务已经完成则get就会返回结果或者抛出异常,如果任务还在执行则get方法会被阻塞。且如果任务抛出异常则在get方法中会进行一次包装,将异常包装成ExecutionException抛出,并通过getCause()方法来获取被封装的初始异常,如果任务被取消了则会抛出CancellationException,但在java8中这个异常被取消了(原因有待查询)

在Executor中有两种任务表现形式:

    <T> Future<T> submit(Callable<T> task);
    <T> Future<T> submit(Runnable task, T result);
    Future<?> submit(Runnable task);

Runnable作为基本的任务表现形式但存在一些局限性,这些局限性和Runnable自身相关,即不能返回一个值也不能抛出异常。

Callable弥补了Runable的缺点:可以返回一个值也能抛出异常。

对于需要返回值的任务用Callable这样的表示形式,不需要抛异常和无返回值的用Runnable这样的表现形式。

在这里还需要注意异常的处理方式,有一篇不错的博文可以看看,是关于submit提交方式和execute提交任务对异常的处理方式。

java多线程中的异常处理_进化的深山猿-CSDN博客_cancellationexception怎么解决

上一篇:Servlet


下一篇:java socket聊天室