Java新建一個子線程異步運行方法

如何在運行主方法的同時異步運行另一個方法,我是用來更新緩存;

1. 工具類

public class ThreadPoolUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPoolUtils.class);
    private static final String POOL_NAME = "thread-im-runner";
    // 等待隊列長度
    private static final int BLOCKING_QUEUE_LENGTH = 20000;
    // 閒置線程存活時間
    private static final int KEEP_ALIVE_TIME = 5 * 1000;
    private static ThreadPoolExecutor threadPool = null;

    private ThreadPoolUtils() {
        throw new IllegalStateException("utility class");
    }

    /**
     * 無返回值直接執行
     *
     * @param runnable 需要運行的任務
     */
    public static void execute(Runnable runnable) {
        getThreadPool().execute(runnable);
    }

    /**
     * 有返回值執行 主線程中使用Future.get()獲取返回值時,會阻塞主線程,直到任務執行完畢
     *
     * @param callable 需要運行的任務
     */
    public static <T> Future<T> submit(Callable<T> callable) {
        return getThreadPool().submit(callable);
    }

    private static synchronized ThreadPoolExecutor getThreadPool() {
        if (threadPool == null) {
            // 核心線程數、最大線程數、閒置線程存活時間、時間單位、線程隊列、線程工廠、當前線程數已經超過最大線程數時的異常處理策略
            threadPool = new ThreadPoolExecutor(50, 500, KEEP_ALIVE_TIME, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(BLOCKING_QUEUE_LENGTH),
                new ThreadFactoryBuilder().setNameFormat(POOL_NAME + "-%d").build(),
                new ThreadPoolExecutor.AbortPolicy() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                        LOGGER.warn("線程過多,當前運行線程總數:{},活動線程數:{}。等待隊列已滿,等待運行任務數:{}", e.getPoolSize(), e.getActiveCount(),
                            e.getQueue().size());
                    }
                });
        }
        return threadPool;
    }

    private static synchronized ThreadPoolExecutor getThreadPoolByCpuNum() {
        if (threadPool == null) {
            // 獲取處理器數量
            int cpuNum = Runtime.getRuntime().availableProcessors();
            // 根據cpu數量,計算出合理的線程併發數
            int maximumPoolSize = cpuNum * 2 + 1;
            // 核心線程數、最大線程數、閒置線程存活時間、時間單位、線程隊列、線程工廠、當前線程數已經超過最大線程數時的異常處理策略
            threadPool = new ThreadPoolExecutor(maximumPoolSize - 1, maximumPoolSize, KEEP_ALIVE_TIME,
                TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(BLOCKING_QUEUE_LENGTH),
                new ThreadFactoryBuilder().setNameFormat(POOL_NAME + "-%d").build(),
                new ThreadPoolExecutor.AbortPolicy() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
                        LOGGER.warn("線程爆炸了,當前運行線程總數:{},活動線程數:{}。等待隊列已滿,等待運行任務數:{}", e.getPoolSize(), e.getActiveCount(),
                            e.getQueue().size());
                    }
                });
        }
        return threadPool;
    }
}

2.實際使用

    ThreadPoolUtils.execute(() -> {
            this.Method();
        });

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章