zoukankan      html  css  js  c++  java
  • 聊聊高并发(三十九)解析java.util.concurrent各个组件(十五) 理解ExecutorService接口的设计

    上一篇讲了Executor接口的设计,目的是将任务的运行和任务的提交解耦。能够隐藏任务的运行策略。这篇说说ExecutorService接口。它扩展了Executor接口,对Executor的生命周期进行管理。并进行了进一步的扩展。


    Executor负责执行任务。

    它的生命周期有3个:执行,关闭和已终止。

    在执行的不论什么时刻,有些 任务可能已经完毕,有些可能正在执行,有些可能正在队列中等待执行。所以假设要关闭Executor的话。就有多种方式,比方优雅平滑的关闭,当执行关闭时就不在接受新的任务请求,而且等到已执行的任务执行完毕再关闭Executor;比方最粗暴的关闭,直接关闭Executor,无论在执行的任务是否执行完毕。

    1. shutdown()方法是优雅关闭的方式

    2. shutdownNow()是粗暴关闭的方式。它返回一个还未開始运行的任务的列表。

    对于正在运行的任务,它採用Thread.interrupt()的方式来取消任务。

    假设任务不响应线程的中断,那么这个任务可能会一直运行。

    3. awaitTermination()方法会等待一段时间再来终止运行的任务

    public interface ExecutorService extends Executor {
    
        void shutdown();
    
        List<Runnable> shutdownNow();
        
        boolean isShutdown();
    
        
        boolean isTerminated();
    
        boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException;
    
    
        <T> Future<T> submit(Callable<T> task);
    
        
        <T> Future<T> submit(Runnable task, T result);
    
       
        Future<?> submit(Runnable task);
    
      
        <T> List<Future<T>> invokeAll(Collection<?

    extends Callable<T>> tasks) throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException; <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<?

    extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }


    ExecutorService的JavaDoc里面的这段代码展示了两阶段来关闭Executor的方式

    1. 先用shutdown()来停止接受新的任务

    2. 再用awaitTermination()方法等待一段时间来让运行的任务运行完毕。再shutdownNow()强制关闭(採用Thread.interrupt()的方式)。再次awaitTermination()等待一段时间,这里是针对上面说的不响应Thread.interrupt()的任务。假设还没有terminated。就提示Executor没有完毕关闭,还有线程在运行任务。

     void shutdownAndAwaitTermination(ExecutorService pool) {
       pool.shutdown(); // Disable new tasks from being submitted
      try {
         // Wait a while for existing tasks to terminate
          if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
          pool.shutdownNow(); // Cancel currently executing tasks
            // Wait a while for tasks to respond to being cancelled
           if (!pool.awaitTermination(60, TimeUnit.SECONDS))
               System.err.println("Pool did not terminate");
          }
        } catch (InterruptedException ie) {
         // (Re-)Cancel if current thread also interrupted
          pool.shutdownNow();
          // Preserve interrupt status
         Thread.currentThread().interrupt();
        }
     }

    除了关闭Executor和检查Executor状态的方法外,ExecutorService还定义了一系列的submit()和invoke()来支持任务异步运行和批量运行。

    submit()方法支持Callable接口和普通的Runnable接口,它的目的是返回一个Future对象来支持任务的异步运行。调用者能够通过Future对象来检查任务的运行状态。后面会详细介绍Future相关的内容。

    invokeAll()和invokeAny()提供了批量运行任务的接口。


  • 相关阅读:
    关于angular2跳路由防止页面刷新的做法(Angular2路由重载)
    使用JavaScript获取前一周的日期
    关于使用css变量实现主题的切换效果
    关于后端下载后端返回的blob类型文件的下载
    关于前端使用JavaScript无法实现canvas打印问题的解决
    项目管理必备:四款免费但好用的项目管理工具
    高效时间管理的18个黄金法则
    与领导相处,一定要谨记这六句话
    努力工作真能让你进步吗?
    如何在项目管理中建立起良好的团队协作关系
  • 原文地址:https://www.cnblogs.com/lytwajue/p/6814871.html
Copyright © 2011-2022 走看看