實際開發過程中我們經常會用到線程池去執行一些任務,降低頻繁創建線程帶來的一些性能損耗,現將自己開發過程中自己定義的線程池分享給大家,希望能幫助到大家,同時歡迎大家進行評閱補充
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import javax.annotation.PreDestroy;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
@Component
public class ExecutorPoolUtil {
// 核心線程數
public static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
// 最大線程數
public static final int MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;
//
public static final int KEEP_ALIVE_TIME = 60;
// 最大阻塞隊列
private static final int MAX_QUEUE = 200;
private static ExecutorService executorService;
// slfj 日誌
private static final Logger logger = LoggerFactory.getLogger(ExecutorPoolUtil.class);
static {
logger.info("開始初始化線程池工具類,核心線程數:{},最大線程數:{},超出線程最大存活時間:{}s", CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME);
executorService = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, new LinkedBlockingQueue<Runnable>(MAX_QUEUE),
new ThreadFactory() {
// 記錄線程名稱,便於日誌排查問題
private final AtomicInteger threadNum = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
Thread thread = null;
try {
thread = new Thread(r);
} catch (Exception e) {
e.printStackTrace();
}
thread.setName("ExecutorPoolUtil-thread-" + threadNum);
thread.setDaemon(false);
thread.setPriority(Thread.NORM_PRIORITY);
return thread;
}
}, );
logger.info("初始化線程池結束");
}
// 對外提供獲得線程池對象方法
public static ExecutorService getExecutorService() {
return executorService;
}
public static void main(String[] args) {
ThreadLocal threadLocal = new ThreadLocal();
}
// 工具類一般將空參構造私有化
private ExecutorPoolUtil() {
}
// 對外提供工具類線程執行方法
public static void execute(Runnable runnable) {
Assert.notNull(runnable, "線程池初始化失敗,不能執行任務");
logger.info("executorService.execute 開始執行線程");
executorService.execute(runnable);
}
// 銷燬線程池對象
@PreDestroy
public void destory() {
// 線程池拒絕接受新的任務,等待執行中的任務
executorService.shutdown();
while (true) {
// 判斷執行中的任務是否結束
if (executorService.isTerminated()) {
logger.info("所有線程任務執行結束");
break;
}
// 若任務未執行結束,線程sleep
try {
Thread.sleep(5l);
logger.info("線程尚未執行結束,繼續等待。。。");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
logger.error(e.getMessage(), e);
}
}
}
public static boolean isFull() {
int activeCount = ((ThreadPoolExecutor) executorService).getActiveCount();
if (MAX_POOL_SIZE == activeCount) {
return true;
}
return false;
}
// 自定義拒絕策略(可以選擇默認等其他策略,根據業務需求定)
private static class WaitPolicy implements RejectedExecutionHandler {
private static final Logger logger = LoggerFactory.getLogger(WaitPolicy.class);
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
try {
executor.getQueue().offer(r, 60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
logger.error(e.getMessage(),e);
}
}
}
}