优秀的编程知识分享平台

网站首页 > 技术文章 正文

线程池关闭(线程池关闭的使用方式)

nanyue 2024-09-01 20:38:27 技术文章 7 ℃

线程池状态

  • RUNNING:正常的状态:接受新的任务,处理等待队列中的任务
  • SHUTDOWN:不接受新的任务提交,但是会继续处理等待队列中的任务
  • STOP:不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程
  • TIDYING:所有的任务都销毁了,workCount 为 0。线程池的状态在转换为 TIDYING 状态时,会执行钩子方法 terminated()
  • TERMINATED:terminated() 方法结束后,线程池的状态就会变成这个
 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    // COUNT_BITS 设置为 29(32-3),前三位用于存放线程状态,后29位用于存放线程数
    // 00000000000000000000000000011101
    private static final int COUNT_BITS = Integer.SIZE - 3;
    // 000 11111111111111111111111111111
    // 线程池的最大线程数是 2^29-1=536870911
    // 减1之后高三位为 0,其他为1
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
    // runState is stored in the high-order bits
    // 线程池的状态存放在高 3 位中
    // 11100000000000000000000000000000
    private static final int RUNNING    = -1 << COUNT_BITS;
    // 00000000000000000000000000000000
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    // 00100000000000000000000000000000
    private static final int STOP       =  1 << COUNT_BITS;
    // 01000000000000000000000000000000
    private static final int TIDYING    =  2 << COUNT_BITS;
    // 01100000000000000000000000000000
    private static final int TERMINATED =  3 << COUNT_BITS;

    // Packing and unpacking ctl
    //  & 两个数都为1则为1,否则为0
    // 将整数 c 的低 29 位修改为 0,就得到了线程池的状态
    // ~CAPACITY 111 00000000000000000000000000000
    private static int runStateOf(int c)     { return c & ~CAPACITY; }
    
    // 将整数 c 的高 3 为修改为 0,就得到了线程池中的线程数
    // CAPACITY 000 11111111111111111111111111111
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    private static int ctlOf(int rs, int wc) { return rs | wc; }

shutdown()

关闭线程池,已提交的任务继续执行,不接受继续提交新任务。

shutdownNow()

shutdownNow相对于shutdown的加强版,区别在于它会去停止当前正在进行的任务。

关闭线程池,尝试停止正在执行的所有任务,不接受继续提交新任务。

返回任务队列中正在等待的所有任务转移到一个 List ,此时可以进行其他操作。

判断线程池是否关闭

isShutdown()

线程是否开始执行了shutdown方法。

当isShutdown返回true并不代表这个线程池是关闭状态了,只代表着线程有没有开始执行线程关闭的方法。

isTerminated()

如果调用了 shutdown() 或 shutdownNow() 方法后,所有任务结束了,那么返回true。

这个方法必须在调用shutdown或shutdownNow方法之后调用才会返回true。

awaitTermination()

等待所有任务完成,并设置超时时间。

实际应用中是,先调用 shutdown 或 shutdownNow,再调这个方法等待所有的线程真正地完成,返回值意味着有没有超时。

代码

shutdown();
List<Runnable> list = shutdownNow()
  protected void cancelRemainingTask(Runnable task) {
  if (task instanceof Future) {
    ((Future<?>) task).cancel(true);
  }
}  
private void awaitTerminationIfNecessary(int awaitTerminationSeconds) {
    if (this.awaitTerminationSeconds <= 0) {
        return;
    }
    try {
        if (!awaitTermination(this.awaitTerminationSeconds, TimeUnit.SECONDS)) {
            log.warn("等待线程池终止超时");
        }
    } catch (InterruptedException ex) {
        log.warn("等待线程池终止超时被打断");
        Thread.currentThread().interrupt();
    }
}



Tags:

最近发表
标签列表