如何获取线程池ThreadPoolExecutor正在运行的线程?
这里有两种方法,如下代码:

package com.itbac.thread;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;
import java.util.stream.Stream;
/**
* ThreadPoolExecutor 的 beforeExecute() 和 afterExecute()方法,
* 不是继承自 AbstractExecutorService , 这是设计上的一个败笔。
* 例如 netty 就是去实现 AbstractExecutorService的
*
* 线程池问题:如何获取线程池ThreadPoolExecutor正在运行的线程?
*/
public class ThreadPoolExecutorThreadQuestion {
public static void main(String[] args) throws InterruptedException {
//main 线程启动子线程,子线程的创造来自于 Executors.defaultThreadFactory()
ExecutorService executorService = Executors.newCachedThreadPool();
//定义线程容器,通过java的引用类型记录数据。
Set<Thread> threadsContainer = new HashSet<>();
//自定义的方法
setThreadFactory(executorService, threadsContainer);
for (int i = 0; i < 5; i++) {
executorService.submit(() -> {
});
}
//线程池等待执行 3 ms
executorService.awaitTermination(3, TimeUnit.MILLISECONDS);
threadsContainer.stream().
//过滤调不存活
filter(Thread::isAlive).
forEach(thread -> System.out.println("方法1:线程池的线程:" + thread)
);
//方法二:
Thread mainThread = Thread.currentThread();
ThreadGroup mainThreadThreadGroup = mainThread.getThreadGroup();
//获取线程组中的线程。
int count = mainThreadThreadGroup.activeCount();
System.out.println("count:"+count);
Thread[] threads = new Thread[count];
//enumerate 枚举,recurse 递归
mainThreadThreadGroup.enumerate(threads, true);
Stream.of(threads).filter(Thread::isAlive).forEach(thread -> System.out.println("方法2:线程池的线程:" + thread ));
//关闭线程池
executorService.shutdown();
/**
* 输出结果:
方法1:线程池的线程:Thread[pool-1-thread-3,5,main]
方法1:线程池的线程:Thread[pool-1-thread-1,5,main]
方法1:线程池的线程:Thread[pool-1-thread-4,5,main]
方法1:线程池的线程:Thread[pool-1-thread-5,5,main]
方法1:线程池的线程:Thread[pool-1-thread-2,5,main]
count:7
方法2:线程池的线程:Thread[main,5,main] 主线程
方法2:线程池的线程:Thread[Monitor Ctrl-Break,5,main] 控制中断监视器
方法2:线程池的线程:Thread[pool-1-thread-1,5,main]
方法2:线程池的线程:Thread[pool-1-thread-2,5,main]
方法2:线程池的线程:Thread[pool-1-thread-3,5,main]
方法2:线程池的线程:Thread[pool-1-thread-4,5,main]
方法2:线程池的线程:Thread[pool-1-thread-5,5,main]
*/
}
private static void setThreadFactory(ExecutorService executorService,Set<Thread> threadsContainer){
if (executorService instanceof ThreadPoolExecutor) {
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executorService;
//获取线程工厂
ThreadFactory oldThreadFactory = threadPoolExecutor.getThreadFactory();
//在把线程工程设置到包装类 DelegatingThreadFactory ,再设置回线程池。
threadPoolExecutor.setThreadFactory(new MyThreadFactory(oldThreadFactory,threadsContainer));
}
}
//我的的线程工厂
private static class MyThreadFactory implements ThreadFactory {
private final ThreadFactory threadFactory;
private final Set<Thread> threadsContainer;
private MyThreadFactory(ThreadFactory threadFactory, Set<Thread> threadsContainer) {
this.threadFactory = threadFactory;
this.threadsContainer = threadsContainer;
}
@Override
public Thread newThread(Runnable r) {
Thread thread = threadFactory.newThread(r);
//cache thread 记录线程
threadsContainer.add(thread);
//删除不存活的线程
// threadsContainer.removeIf(next -> !next.isAlive());
return thread;
}
}
}

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!