JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

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

wys521 2024-11-18 18:00:12 精选教程 28 ℃ 0 评论
  • 难度:中级
  • 开发语言: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();
    }
}

运行结果:


文字版:

线程池是否开始关闭: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线程池核心(十二):提交任务后做了什么?

学习小组

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

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

(此处已添加圈子卡片,请到今日头条客户端查看)

版权声明

原创不易,未经允许不得转载!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表