zoukankan      html  css  js  c++  java
  • java Executor, ExecutorService, Executors 有什么不同

    Executor 是一个接口,只定义了一个方法, 可以接收Runnable实例,用来执行一个实现Runnable接口的任务。

    void execute(Runnable command);

    ExecutorService 也是一个接口,继承自Executor,并增加了一些方法,用的比较广泛,提供了一些生命周期的方法。shutdown,还有submit方法返回值是future。

    ExecutorService就是为了解决执行服务的生命周期问题的。

    ExecutorService的生命周期有3种状态:运行,关闭和已终止。

    在初始创建时处于运行状态。

    Shutdown方法将执行平缓的关闭过程;不再接受新的任务,同时等待已经提交的任务执行完成——包括那些还未开始执行的任务。

    Shutdownnow方法将执行粗暴的关闭过程,它将尝试取消所有运行中的任务,并且不再启动队列中尚未开始执行的任务。

    等所有任务都完成后,ExecutorService将转入终止状态。

    可以调用awaitTermination来等待ExecutorService到达终止状态。

    通过isTerminated来轮询ExecutorService是否已经终止。

     1 /**
     2  * An {@link ExecutorService} that executes each submitted task using
     3  * one of possibly several pooled threads, normally configured
     4  * using {@link Executors} factory methods.
     5  *
     6 ExecutorService用线程池中的每个线程执行提交进来的任务,通常由Executors中的工厂方法配置而成的。
     7  * <p>Thread pools address two different problems: they usually
     8  * provide improved performance when executing large numbers of
     9  * asynchronous tasks, due to reduced per-task invocation overhead,
    10  * and they provide a means of bounding and managing the resources,
    11  * including threads, consumed when executing a collection of tasks.
    12  * Each {@code ThreadPoolExecutor} also maintains some basic
    13  * statistics, such as the number of completed tasks.
    14  *
    15  线程池解决了两个不同的问题: 他们通常在执行大量异步任务时提供了改善的性能,
    16  由于减少了每个任务调用开销,并且提供了一种bounding(边界,限制)和管理资源的手段,
    17  包括线程,当执行一系列任务时消费。
    18  每个线程池也维护了一些基本的统计信息,例如已经完成的任务数量。
    19  * <p>To be useful across a wide range of contexts, this class
    20  * provides many adjustable parameters and extensibility
    21  * hooks. However, programmers are urged to use the more convenient
    22  * {@link Executors} factory methods {@link
    23  * Executors#newCachedThreadPool} (unbounded thread pool, with
    24  * automatic thread reclamation), {@link Executors#newFixedThreadPool}
    25  * (fixed size thread pool) and {@link
    26  * Executors#newSingleThreadExecutor} (single background thread), that
    27  * preconfigure settings for the most common usage
    28  * scenarios. Otherwise, use the following guide when manually
    29  * configuring and tuning this class:
    30  *
    31  为了在广泛的上下文中发挥作用,这个类提供了许多可以调整的参数和可延伸的钩子。
    32  然而,还是推荐程序员用更加方便的Executors的工厂方法来创建不同种的线程池。
    33  即最常用的预配置设置情景。否则,手动操作时请使用以下指南配置和调整此类。
    34  * <dl>
     1 void shutdown();
     2 List<Runnable> shutdownNow();
     3 boolean isShutdown();
     4 boolean isTerminated();
     5 boolean awaitTermination(long timeout, TimeUnit unit)
     6         throws InterruptedException;
     7 <T> Future<T> submit(Callable<T> task);
     8 <T> Future<T> submit(Runnable task, T result);
     9 Future<?> submit(Runnable task);
    10 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
    11         throws InterruptedException;
    12 <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
    13                                   long timeout, TimeUnit unit)
    14         throws InterruptedException;
    15 <T> T invokeAny(Collection<? extends Callable<T>> tasks)
    16         throws InterruptedException, ExecutionException;
    17 <T> T invokeAny(Collection<? extends Callable<T>> tasks,
    18                     long timeout, TimeUnit unit)
    19         throws InterruptedException, ExecutionException, TimeoutException;

    Executors 是静态工厂类,可以用它创建出各种各样的线程池。 一般像下面这么用。

    ScheduledExecutorService service=Executors.newScheduledThreadPool(int corePoolSize); 

     1 public static ExecutorService newFixedThreadPool(int nThreads) {
     2         return new ThreadPoolExecutor(nThreads, nThreads,
     3                                       0L, TimeUnit.MILLISECONDS,
     4                                       new LinkedBlockingQueue<Runnable>());
     5     }
     6     
     7     public static ExecutorService newSingleThreadExecutor() {
     8         return new FinalizableDelegatedExecutorService
     9             (new ThreadPoolExecutor(1, 1,
    10                                     0L, TimeUnit.MILLISECONDS,
    11                                     new LinkedBlockingQueue<Runnable>()));
    12     }
    13     public static ExecutorService newCachedThreadPool() {
    14         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
    15                                       60L, TimeUnit.SECONDS,
    16                                       new SynchronousQueue<Runnable>());
    17     }
    18     public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    19         return new DelegatedScheduledExecutorService
    20             (new ScheduledThreadPoolExecutor(1));
    21     }
    22     public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    23         return new ScheduledThreadPoolExecutor(corePoolSize);
    24     }
    25     public static ScheduledExecutorService newScheduledThreadPool(
    26             int corePoolSize, ThreadFactory threadFactory) {
    27         return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
    28     }

    可以看到

    newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) 这个方法可以传入线程池的大小,线程工厂,这里表明,我们可以自己实现一个工厂来创建所需要的线程池。

    我们想想问什么要有Executor,ExecutorService这些类。我们用Thread类不行吗。

    在java类库中,任务执行的主要抽象不是Thread,而是Executor,

    它提供了一种标准的方法将任务的提交过程与执行过程解耦开来,并用Runnable来表示任务。Executor的实现还提供了对生命周期的支持,以及统计信息收集,应用程序管理机制和性能监视等机制。

    执行策略:

    通过将任务的提交与执行解耦开来,从而无须太大的困难就可以为某种类型的任务指定和修改执行策略。在执行策略中定义了任务执行的what,where,when,how等方面,包括:

    在什么(what)线程中执行任务

    任务按照什么(what)顺序执行(FIFO,LIFO,优先级)

    有多少个(How many)任务能并发执行

    在队列中有多少个(how many)任务在等待执行

    如果系统由于过载而需要拒绝一个任务,那么应该选择哪一个(which) 任务?另外,如何(how)通知应用程序有任务被拒绝?

    在执行一个任务之前或之后,应该进行哪些(what)动作?

    各种执行策略都是一种资源管理工具,最佳策略取决于可用的计算资源以及对服务质量的需求。通过限制并发任务的数量,可以确保应用程序不会由于资源耗尽而失败,或者由于在稀缺资源上发生竞争而严重影响性能。通过将任务的提交与任务的执行策略分离开来,有助于在部署阶段选择与可用硬件资源最匹配的执行策略。

     线程池:

    好处: 在线程池中执行任务比为每个任务分配一个线程优势更多。通过重用现有的线程而不是创建线程,可以在处理多个请求时分摊在线程创建和销毁过程中产生的开销。另一个好处是,当请求到达时,工作线程通常已经存在,因此不会因为等待创建线程而延迟任务的执行。

    下面是Executors可以创建的各种线程池。

  • 相关阅读:
    Hive小结
    Redis小结
    Hbase小结
    Rdd/DataFrame/DataSet 小结
    spark杂记2
    shiyan
    stanford推荐阅读目录
    超市收银系统之——3
    超市收银系统之超市类——4
    超市收银系统_仓库类——2
  • 原文地址:https://www.cnblogs.com/liumy/p/11657805.html
Copyright © 2011-2022 走看看