1. 程式人生 > >java執行緒池優化,不再使用Executors建立執行緒池

java執行緒池優化,不再使用Executors建立執行緒池

今天在使用之前的執行緒池工具的時候,阿里的程式碼規範外掛提示不要這樣建立執行緒池。看了外掛做出的說明決定將執行緒池工具改為如下:


import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.util.concurrent.*;

/**
 *
 * 執行緒池不允許使用Executors去建立,而是通過ThreadPoolExecutor的方式,這樣的處理方式讓寫的同學更加明確執行緒池的執行規則,規避資源耗盡的風險。 說明:Executors各個方法的弊端:
 * 1)newFixedThreadPool和newSingleThreadExecutor:
 *   主要問題是堆積的請求處理佇列可能會耗費非常大的記憶體,甚至OOM。
 * 2)newCachedThreadPool和newScheduledThreadPool:
 *   主要問題是執行緒數最大數是Integer.MAX_VALUE,可能會建立數量非常多的執行緒,甚至OOM。
 * @author wangjie
 */
public class ThreadPoolUtil { private volatile static ExecutorService executorService; private ThreadPoolUtil(){} public static ExecutorService getExecutorService() { if (executorService == null) { synchronized (ThreadPoolUtil.class) { /** * 使用谷歌的guava框架 * ThreadPoolExecutor引數解釋 * 1.corePoolSize 核心執行緒池大小 * 2.maximumPoolSize 執行緒池最大容量大小 * 3.keepAliveTime 執行緒池空閒時,執行緒存活的時間 * 4.TimeUnit 時間單位 * 5.ThreadFactory 執行緒工廠 * 6.BlockingQueue任務佇列 * 7.RejectedExecutionHandler 執行緒拒絕策略 */
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build(); executorService = new ThreadPoolExecutor(10, 20, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024),
namedThreadFactory, new ThreadPoolExecutor.AbortPolicy()); } } return executorService; } }

其中,使用ThreadFactoryBuilder需要用到谷歌的guava框架,maven依賴為:

		<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>26.0-jre</version>
        </dependency>

另外,spring也提供了相似的工具

  public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
        // 設定核心執行緒數
        threadPool.setCorePoolSize(5);
        // 設定最大執行緒數
        threadPool.setMaxPoolSize(10);
        // 執行緒池所使用的緩衝佇列
        threadPool.setQueueCapacity(25);
        // 設定執行緒活躍時間(秒)
        threadPool.setKeepAliveSeconds(60);
        // 等待所有任務結束後再關閉執行緒池
        threadPool.setWaitForTasksToCompleteOnShutdown(true);
        // 執行緒名稱字首
        threadPool.setThreadNamePrefix(blockChainExecer);
        // 初始化執行緒
        threadPool.initialize();
        return threadPool;
    }