zoukankan      html  css  js  c++  java
  • 如何获取线程池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;
            }
        }
    
    }
  • 相关阅读:
    在ensp上配置Trunk接口
    在ensp上VLAN基础配置以及Access接口
    在ensp上的ARP及Proxy ARP
    在ensp上简单的配置交换机
    1000000 / 60S 的 RocketMQ 不停机,扩容,平滑升级!
    DE1-SOC 只要加载驱动VNC就断开(DE1-SOC 只要加载驱动串口就卡住)
    通过U盘拷贝文件到DE1-SOC 的 Linux系统
    Linux 系统响应来自 FPGA 端的中断的中断号到底怎么对应?(GIC控制器)
    HPS 访问 FPGA 方法之五—— 通过FPGA 中断访问
    HPS 访问 FPGA 方法之四—— 编写 Linux 字符设备驱动
  • 原文地址:https://www.cnblogs.com/itbac/p/12210680.html
Copyright © 2011-2022 走看看