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