ThreadPoolService.java 2.85 KB
package com.diligrp.cashier.shared.service;

import java.util.concurrent.*;

/**
 * 请谨慎使用此线程池工具类,通常建议根据特定的使用场景设置线程池参数,不建议使用统一的线程池配置
 * JDK的线程池类并不能很好区分"计算密集型"和"IO密集型"任务类型,应该根据不同的任务类型去配置不同的参数
 */
public final class ThreadPoolService {

    private static final int CPU_CORE_NUM = Runtime.getRuntime().availableProcessors();

    private static final int CPU_MAX_POOL_SIZE = 100;

//    private static final int IO_MAX_POOL_SIZE = 1000;

    // CPU运算密集型任务的线程池实例
    private static volatile ExecutorService cpuThreadPoll;

    // IO密集型任务的线程池实例
    private static volatile ExecutorService ioThreadPoll;

    private ThreadPoolService() {
    }

    /**
     * 获取运算密集型任务的线程池实例
     * 通常建议根据特定的使用场景设置线程池参数,不建议使用统一的线程池配置
     */
    public static ExecutorService getCpuThreadPoll() {
        if (cpuThreadPoll == null) {
            synchronized (ThreadPoolService.class) {
                if (cpuThreadPoll == null) {
                    cpuThreadPoll = new ThreadPoolExecutor(CPU_CORE_NUM + 1, CPU_MAX_POOL_SIZE, 20,
                        TimeUnit.SECONDS, new LinkedBlockingQueue<>(100), new LazyRejectedExecutionHandler());
                }
            }
        }
        return cpuThreadPoll;
    }

    /**
     * 获取IO密集型任务的线程池实例
     * 通常建议根据特定的使用场景设置线程池参数,不建议使用统一的线程池配置
     */
    public static ExecutorService getIoThreadPoll() {
        if (ioThreadPoll == null) {
            synchronized (ThreadPoolService.class) {
                if (ioThreadPoll == null) {
                    ioThreadPoll = Executors.newVirtualThreadPerTaskExecutor();

//                    ioThreadPoll = new ThreadPoolExecutor(CPU_CORE_NUM + 1, IO_MAX_POOL_SIZE, 20,
//                        TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000), new LazyRejectedExecutionHandler());
                }
            }
        }
        return ioThreadPoll;
    }

    private static class LazyRejectedExecutionHandler implements RejectedExecutionHandler {
        @Override
        public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) {
            boolean success = false;
            try {
                success = executor.getQueue().offer(task, 15, TimeUnit.SECONDS);
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }

            if (!success) {
                throw new RejectedExecutionException("task queue is full");
            }
        }
    }
}