• 如何获取线程池ThreadPoolExecutor正在运行的线程


    如何获取线程池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;
            }
        }
    
    }
  • 相关阅读:
    Sqlserver2005迁移至Oracle系列之二:生成存储过程
    Sqlserver:在sql2005查看索引的碎片统计情况,并给出处理意见的自动化批处理脚本
    Sqlserver:利用Sqlserver2005的数据库触发器开发的数据库审核追踪系统,可以跟踪对象的修改信息及修改源代码
    Sqlserver2005迁移至Oracle系列之一:生成表
    中国软件业的现状浅析
    Java之异常与错误的区别及java的异常体系
    SQL优化34条
    swftools转换文件时线程堵塞问题的解决方法
    中国软件开发需要注意的地方
    Flex 应用内存泄露的分析与诊断
  • 原文地址:https://www.cnblogs.com/itbac/p/12210680.html
Copyright © 2020-2023  润新知