chapter07_取消与关闭_2_停止基于线程的服务

  • (1) 线程池是线程的所有者,应用程序不是线程的所有者,所以应用程序不能直接停止线程,而是交给线程池处理

    (2) 线程池应该提供__生命周期方法__,来关闭自己以及所拥有的线程

    (3) __对于持有线程的服务,只要服务的存在时间大于创建线程的方法的存在时间,那么就应该提供生命周期方法

  • 关闭ExecutorService

    在复杂程序中,通常会将ExecutorService封装在某个高级别的服务中

    示例

      public class LogService {
    
          private final ExecutorService exec = newSingleExecutor();
          private final PrintWriter writer;
    
          ...
    
          public stop() throws InterruptedException {
    
              try {
    
                  exec.shutdown();
                  exec.awaitTermination(TIMEOUT, UNIT);
              } finally {
                  writer.close();
              }
          }
    
          ...
      }
    

    awaitTermination()方法:阻塞直到超时或任务都完成

  • shutdownNow()方法的局限性

    (1) shutdownNow()方法的返回值是List,它返回的是那些从未开始的任务,而不是完成了一半被迫中止的任务

    (2) ExecutorService接口没有提供任何可以返回完成了一半的任务,所以只能自己实现

      public class TrackingExecutor extends AbstractExecutorService {
    
          private final ExecutorService exec;
    
          private final Set<Runnable> tasksCancelledAtShutdown = Collections.synchronizedSet(new HashSet<Runnable>());
    
          ...
    
          public List<Runnable> shutdownNow() {
    
              return exec.shutdownNow();
          }
    
          public boolean isShutdown() {
    
              return exec.isShutdown();
          }
    
          public List<Runnable> getCancelledTasks() {
    
              if (!exec.isTerminated()) {
                  throw new IllegalStateException(/*...*/);
              }
    
              return new ArrayList<Runnable>(tasksCancelledAtShutdown);
          }
    
          public void execute(final Runnable runnable) {
    
              exec.execute(new Runnable() {
    
                  public void run() {
                      try {
                          runnable.run();
                      } finally {
                          if (isShutdown() && Thread.currentThread().isInterrupted()) {
                              tasksCancelledAtShutdown.add(runnable);
                          }
                      }
                  }
              });
          }
    
          ...
      }
    

    这里采用的机制是:内部增加一个同步的Set,当当前任务被中断时,判断一下ExecutorService是否被shutdown,如果被shutdown和被中断的条件同时满足,就把当前任务加入Set中,作为getCancelledTasks()的返回值

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值