【並發編程】線程池是否需要手動關閉嗎?以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.如果核心線程數較多,且最大線程數的存活時間較長,請求量不大,則可以手動關閉線程池,減少線程長期存在的性能損耗;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM