网站首页 > java教程 正文
- 难度:中级
- 开发语言: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区别
下一章
学习小组
加入同步学习小组,共同交流与进步。
欢迎加入“人人都是程序员”编程圈子,与圈友一起交流讨论。
(此处已添加圈子卡片,请到今日头条客户端查看)
版权声明
原创不易,未经允许不得转载!
猜你喜欢
- 2024-09-16 java-线程池详解(java线程池入门)
- 2024-09-16 线程进阶:实战应用之Java线程池全面解析
- 2024-09-16 Java开发之高并发必备篇(七)——线程池
- 2024-09-16 Java-线程池专题(什么是线程池,如何使用,为什么要用)
- 2024-09-16 Java线程之Executors线程池的原理和使用
- 2024-09-16 Java的四种线程池的使用,以及自定义线程工厂
- 2024-09-16 探索JAVA并发 - 线程池详解(java多线程并发编程 线程池)
- 2024-09-16 Java线程池的概念及使用(java 线程池原理详解)
- 2024-09-16 Java 线程池(java线程池原理)
- 2024-09-16 技术进阶:Java线程池的使用和原理分析
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)