网站首页 > 精选教程 正文
- 难度:中级
- 开发语言:Java
- 学习时间:20分钟
1.线程池状态
线程池一共有五种状态:
- RUNNING
- SHUTDOWN
- STOP
- TIDYING
- TERMINATED
状态解析:
- RUNNING:线程池正常运行。
- SHUTDOWN:调用 shutdown 方法后,将线程池状态设置为此值,所有空闲线程都将被中断。不再接收新任务,也不再添加新线程。
- STOP:调用 shutdownNow 方法后,将线程池状态设置为此值,所有线程都将被中断。不再接收新任务,也不再添加新线程。
- TIDYING:线程池处于此状态时,任务队列为空,线程数为 0。
- 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。
总结
- 线程池一共有五种状态:
- RUNNING
- SHUTDOWN
- STOP
- TIDYING
- TERMINATED
- RUNNING:线程池正常运行。
- SHUTDOWN:调用 shutdown 方法后,将线程池状态设置为此值,所有空闲线程都将被中断。不再接收新任务,也不再添加新线程。
- STOP:调用 shutdownNow 方法后,将线程池状态设置为此值,所有线程都将被中断。不再接收新任务,也不再添加新线程。
- TIDYING:线程池处于此状态时,任务队列为空,线程数为 0。
- TERMINATED:线程池处于此状态时,表示线程池已关闭。
- boolean isShutdown() 判断线程池是否开始关闭。
- boolean isTerminating() 判断线程池是否正在关闭。
- boolean isTerminated() 判断线程池是否已关闭。
答疑
如果大家有任何疑问,请在下方留言或评论。
上一章
Java线程池核心(十):从源码上分析shutdown与shutdownNow区别
下一章
学习小组
加入同步学习小组,共同交流与进步。
欢迎加入“人人都是程序员”编程圈子,与圈友一起交流讨论。
(此处已添加圈子卡片,请到今日头条客户端查看)
版权声明
原创不易,未经允许不得转载!
- 上一篇: JAVA线程状态及实现
- 下一篇: Java开发之高并发必备篇(四)——线程的状态、调度和操作方法
猜你喜欢
- 2024-11-18 Java并发编程线程状态转换
- 2024-11-18 Java面试必考问题:线程的生命周期
- 2024-11-18 Java 19 虚拟线程的状态变化,停驻与锁定
- 2024-11-18 Java线程生命周期详解?
- 2024-11-18 线程从创建最终消亡,要经历的若干状态,你了解其中的多少?
- 2024-11-18 java线程状态之WAITING(等待)
- 2024-11-18 浅谈Java线程:线程基础知识扫盲
- 2024-11-18 Java线程在各个状态下调用start方法会发生什么事情?
- 2024-11-18 为什么Java中线程没有Running状态
- 2024-11-18 阻塞模型将会使线程休眠,为什么 Java 线程状态却是 RUNNABLE?
你 发表评论:
欢迎- 04-11Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- 04-11Java中你知道几种从字符串中找指定的字符的数量
- 04-11探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- 04-11Python字符串详解与示例(python字符串的常见操作)
- 04-11java正则-取出指定字符串之间的内容
- 04-11String s1 = new String("abc");这句话创建了几个字符串对象?
- 04-11java判断字符串中是否包含某个字符
- 04-11关于java开发中正确的发牌逻辑编写规范
- 最近发表
-
- Java面试“字符串三兄弟”String、StringBuilder、StringBuffer
- Java中你知道几种从字符串中找指定的字符的数量
- 探秘Java面试中问的最多的String、StringBuffer、StringBuilder
- Python字符串详解与示例(python字符串的常见操作)
- java正则-取出指定字符串之间的内容
- String s1 = new String("abc");这句话创建了几个字符串对象?
- java判断字符串中是否包含某个字符
- 关于java开发中正确的发牌逻辑编写规范
- windows、linux如何后台运行jar(并且显示进程名)
- 腾讯大佬私人收藏,GitHub上最受欢迎的100个JAVA库,值得学习
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)