java 线程池_Java线程池核心(十一):线程池状态

  • 难度:中级
  • 开发语言:Java
  • 学习时间:20分钟

1.线程池状态

线程池一共有五种状态:

  1. RUNNING
  2. SHUTDOWN
  3. STOP
  4. TIDYING
  5. TERMINATED

状态解析:

  1. RUNNING:线程池正常运行。
  2. SHUTDOWN:调用 shutdown 方法后,将线程池状态设置为此值,所有空闲线程都将被中断不再接收新任务,也不再添加新线程
  3. STOP:调用 shutdownNow 方法后,将线程池状态设置为此值,所有线程都将被中断不再接收新任务,也不再添加新线程
  4. TIDYING:线程池处于此状态时,任务队列为空线程数为 0
  5. TERMINATED:线程池处于此状态时,表示线程池已关闭

源码:

private static final int RUNNING    = -1 << COUNT_BITS;private static final int SHUTDOWN   =  0 << COUNT_BITS;private static final int STOP       =  1 << COUNT_BITS;private static final int TIDYING    =  2 << COUNT_BITS;private static final int TERMINATED =  3 << COUNT_BITS;

用于记录线程池状态的属性:

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

2.判断线程池状态的方法

公开的:

  • boolean isShutdown()
  • boolean isTerminating()
  • boolean isTerminated()

私有的:

  • isRunning(int c)
  • boolean isStopped()

3.isRunning(int c) 方法源码分析

/** * 判断线程池状态是否为RUNNING *  * @param c ctl值。 */private static boolean isRunning(int c) {  // 判断 ctl 值是否小于 SHUTDOWN  // true:是  // false:不是/**    return c < SHUTDOWN;}

4.boolean isStopped() 方法源码分析

/** * 判断线程池状态是否为STOP */boolean isStopped() {  // 判断 ctl值是否大于或等于STOP  // true:是STOP状态。  // false:不是STOP状态。    return runStateAtLeast(ctl.get(), STOP);}

5.boolean isShutdown() 方法源码分析

/** * 判断线程池是否开始关闭。 */public boolean isShutdown() {  // 判断 ctl值是否大于或等于SHUTDOWN  // true:是SHUTDOWN状态。  // false:不是SHUTDOWN状态。    return runStateAtLeast(ctl.get(), SHUTDOWN);}

6.boolean isTerminating() 方法源码分析

/** * 判断线程池是否正在关闭。 */public boolean isTerminating() {  // 获取当前线程池状态。    int c = ctl.get();  // runStateAtLeast(c, SHUTDOWN):当前线程池状态值 >= SHUTDOWN  // runStateLessThan(c, TERMINATED):当前线程池状态值 < TERMINATED  // 综上所述,SHUTDOWN <= 当前线程池状态值 < TERMINATED,即SHUTDOWN、STOP、TIDYING。    return runStateAtLeast(c, SHUTDOWN) && runStateLessThan(c, TERMINATED);}

7.boolean isTerminated() 方法源码分析

/** * 判断线程池是否已关闭。 */public boolean isTerminated() {  // 当当前线程池状态 >= TERMINATED时,表示线程池已关闭。    return runStateAtLeast(ctl.get(), TERMINATED);}

8.示例

package com.gorhaf;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class Main {    public static void main(String[] args) throws InterruptedException {        // 创建线程池        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>());        // 观察线程池情况        watching(threadPool);        // 提交任务        threadPool.submit(createTask());        // 关闭线程池        threadPool.shutdown();    }    /**     * 创建任务     *     * @return 任务     */    private static Runnable createTask() {        // 创建任务        Runnable task = new Runnable() {            @Override            public void run() {                try {                    // 模拟耗时任务                    TimeUnit.SECONDS.sleep(2);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        };        return task;    }    /**     * 观察线程池内部情况     *     * @param threadPool 线程池     */    private static void watching(ThreadPoolExecutor threadPool) {        Runnable task = new Runnable() {            @Override            public void run() {                for (; ; ) {                    try {                        System.out.println("线程池是否开始关闭:" + threadPool.isShutdown() + ",正在关闭:" + threadPool.isTerminating() + ",已关闭:" + threadPool.isTerminated());                        // 每经过1秒钟获取一次线程池信息                        TimeUnit.SECONDS.sleep(1);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        };        new Thread(task).start();    }}

运行结果:

902600ed3444f4ffb415f2f97c6fa99d.gif

文字版:

线程池是否开始关闭:false,正在关闭:false,已关闭:false线程池是否开始关闭:true,正在关闭:true,已关闭:false线程池是否开始关闭:true,正在关闭:false,已关闭:true线程池是否开始关闭:true,正在关闭:false,已关闭:true线程池是否开始关闭:true,正在关闭:false,已关闭:true

刚开始,线程池没有关闭,所有结果都为 false

接着,调用 threadPool.shutdown() 关闭线程池,还没完成的任务继续执行,等线程池中所有任务都完成再关闭,isShutdown()isTerminating() 都返回true,isTerminated() 返回 false

最后,线程池里都任务都完成,线程池也可以彻底关闭了,isShutdown()isTerminated() 都返回true,isTerminating() 返回 false

总结

  • 线程池一共有五种状态:
  1. RUNNING
  2. SHUTDOWN
  3. STOP
  4. TIDYING
  5. TERMINATED
  • RUNNING:线程池正常运行。
  • SHUTDOWN:调用 shutdown 方法后,将线程池状态设置为此值,所有空闲线程都将被中断不再接收新任务,也不再添加新线程
  • STOP:调用 shutdownNow 方法后,将线程池状态设置为此值,所有线程都将被中断不再接收新任务,也不再添加新线程
  • TIDYING:线程池处于此状态时,任务队列为空线程数为 0
  • TERMINATED:线程池处于此状态时,表示线程池已关闭
  • boolean isShutdown() 判断线程池是否开始关闭。
  • boolean isTerminating() 判断线程池是否正在关闭。
  • boolean isTerminated() 判断线程池是否已关闭。

答疑

如果大家有任何疑问,请在下方留言或评论。

上一章

Java线程池核心(十):从源码上分析shutdown与shutdownNow区别

下一章

Java线程池核心(十二):提交任务后做了什么?

学习小组

加入同步学习小组,共同交流与进步。

欢迎加入“人人都是程序员”编程圈子,与圈友一起交流讨论。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值