zoukankan      html  css  js  c++  java
  • 【并发编程】线程池是否需要手动关闭吗?以Hutool中的线程池为例

    Hutool工具包中使用线程池的API是:

      ThreadUtil.execute()

        /**
         * 直接在公共线程池中执行线程
         *
         * @param runnable 可运行对象
         */
        public static void execute(Runnable runnable) {
            GlobalThreadPool.execute(runnable);
        }

      内部使用的一个名为 GlobalThreadPool的线程池,该线程池使用ExecutorBuilder建造者模式去创建,其线程池的默认参数如下:

    public class GlobalThreadPool {
        private static ExecutorService executor;
    
        private GlobalThreadPool() {
        }
    
        static {
            init();
        }
    
        /**
         * 初始化全局线程池
         */
        synchronized public static void init() {
            if (null != executor) {
                executor.shutdownNow();
            }
            executor = ExecutorBuilder.create().useSynchronousQueue().build();
        }
        private static final long serialVersionUID = 1L;
    
        /** 默认的等待队列容量 */
        public static final int DEFAULT_QUEUE_CAPACITY = 1024;
    
        /**
         * 初始池大小
         */
        private int corePoolSize;
        /**
         * 最大池大小(允许同时执行的最大线程数)
         */
        private int maxPoolSize = Integer.MAX_VALUE;
        /**
         * 线程存活时间,即当池中线程多于初始大小时,多出的线程保留的时长
         */
        private long keepAliveTime = TimeUnit.SECONDS.toNanos(60);
        /**
         * 队列,用于存在未执行的线程
         */
        private BlockingQueue<Runnable> workQueue;
        /**
         * 线程工厂,用于自定义线程创建
         */
        private ThreadFactory threadFactory;
        /**
         * 当线程阻塞(block)时的异常处理器,所谓线程阻塞即线程池和等待队列已满,无法处理线程时采取的策略
         */
        private RejectedExecutionHandler handler;
        /**
         * 线程执行超时后是否回收线程
         */
        private Boolean allowCoreThreadTimeOut;

      可以看到其corePoolSize线程数是0,最大线程数是Integer.max_value,也就是21亿,线程最大存活时间为60s,下面为测试Demo

    public class Test {
    
        public static void main(String[] args) throws Exception {
            final AtomicReference<BigDecimal> REFERENCE = new AtomicReference<>();
            final AtomicInteger atomicInteger =new AtomicInteger();
            CountDownLatch countDownLatch = ThreadUtil.newCountDownLatch(500);
            for (int i = 0; i < 500; i++) {
                final int a = i;
                ThreadUtil.execute(() -> {
                    atomicInteger.incrementAndGet();
                    System.out.println("线程" + a);
                    REFERENCE.set(BigDecimal.valueOf(a));
                    countDownLatch.countDown();
                });
            }
            countDownLatch.await();
            System.out.println("===== Atomic ====="+atomicInteger.get());
            System.out.println("=====SUCCEED=====" + REFERENCE.get());
    
        }
    }

      测试demo可以看到主线程执行完毕后,程序并不会中止,因为子线程仍然存活,60s后程序终止;

    因此这里有个结论:

      1.线程池corePoolSize为0,且最大线程数设置为存活时间,则可以不用关闭线程池,特别是在请求比较密集的情况下,能更好的减少创建线程所需要的时间

      2.如果核心线程数较多,且最大线程数的存活时间较长,请求量不大,则可以手动关闭线程池,减少线程长期存在的性能损耗;

     

  • 相关阅读:
    select和epoll的区别
    Epoll导致的selector空轮询
    2.集合框架中的泛型有什么优点?
    java的语法基础(二)
    17-文本属性和字体属性
    15-浮动
    16-margin的用法
    14-块级元素和行内元素
    12-简单认识下margin
    day15 什么是递归/递归与回溯
  • 原文地址:https://www.cnblogs.com/july-sunny/p/12759265.html
Copyright © 2011-2022 走看看