java線程池與單例模式

1.線程池體系結(jié)構(gòu)

Executor 負(fù)責(zé)線程的使用和調(diào)度的 根接口
|--ExecutorService 接口: 線程池的主要接口。增加了返回Future 對(duì)象
|--ThreadPoolExecutor 線程池的實(shí)現(xiàn)類
|--ScheduledExceutorService 接口: 負(fù)責(zé)線程的調(diào)度
|--ScheduledThreadPoolExecutor : 繼承ThreadPoolExecutor,實(shí)現(xiàn)了ScheduledExecutorService

2.單例模式定義

簡(jiǎn)單理解就是一個(gè)類只能有一個(gè)實(shí)例, 線程池使用中只會(huì)創(chuàng)建一個(gè)實(shí)例

3.餓漢式線程池執(zhí)行工廠

import cn.hutool.core.thread.NamedThreadFactory;
import lombok.NonNull;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 描述:餓漢式 線程池執(zhí)行器工廠.
 * 1.單例
 * 2.不管有沒(méi)有調(diào)用者都會(huì)提前創(chuàng)建實(shí)例,資源利用效率低
 * @author wangkai
 */
public final class HungryThreadPoolFactory {

    private HungryThreadPoolFactory() {
    }

    /**
     * 全局訪問(wèn)點(diǎn).
     * @param runnable runnable
     */
    public static void execute(@NonNull Runnable runnable) {
        getInstance().execute(runnable);
    }

    /**
     * 靜態(tài)公用工廠方法,返回唯一實(shí)例.
     * @return ThreadPoolExecutor
     */
    public static ThreadPoolExecutor getInstance() {
        return HungryThreadPoolFactory.THREAD_POOL_EXECUTOR;
    }

    static final int CPU = Runtime.getRuntime().availableProcessors();
    static final int CORE_POOL_SIZE = CPU + 1;
    static final int MAXIMUM_POOL_SIZE = CPU * 2 + 1;
    static final long KEEP_ALIVE_TIME = 1L;
    static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
    static final int MAX_QUEUE_NUM = 1024;

    /**
     * 靜態(tài)私有成員變量.
     */
    private static ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
            CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT,
            new LinkedBlockingQueue<>(MAX_QUEUE_NUM),
            new NamedThreadFactory("ThreadPoolExecutorFactory-", false),
            new ThreadPoolExecutor.AbortPolicy());
}

4.懶漢式線程池執(zhí)行工廠

import cn.hutool.core.thread.NamedThreadFactory;
import lombok.NonNull;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 描述:懶漢式 線程池執(zhí)行器工廠.
 * 1.單例
 * 2.延遲加載:解決了餓漢式不管有沒(méi)有調(diào)用都創(chuàng)建實(shí)例的弊端。但是多線程訪問(wèn)可能會(huì)創(chuàng)建多個(gè)實(shí)例,所以需要解決線程安全問(wèn)題
 * @author wangkai
 */
public final class LazyThreadPoolFactory {

    private LazyThreadPoolFactory() {
    }

    /**
     * 全局訪問(wèn)點(diǎn).
     * @param runnable runnable
     */
    public static void execute(@NonNull Runnable runnable) {
        getInstance().execute(runnable);
    }

    /**
     * 靜態(tài)私有成員變量.
     */
    private static ThreadPoolExecutor THREAD_POOL_EXECUTOR = null;

    public static ThreadPoolExecutor getInstance() {
        generateInstance();
        return LazyThreadPoolFactory.THREAD_POOL_EXECUTOR;
    }

    static final int CPU = Runtime.getRuntime().availableProcessors();
    static final int CORE_POOL_SIZE = CPU + 1;
    static final int MAXIMUM_POOL_SIZE = CPU * 2 + 1;
    static final long KEEP_ALIVE_TIME = 1L;
    static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
    static final int MAX_QUEUE_NUM = 1024;

    public static void generateInstance() {
        //校驗(yàn)實(shí)例是否已生成,避免多線程訪問(wèn)重復(fù)生成實(shí)例
        if (THREAD_POOL_EXECUTOR == null) {
            THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
                    CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT,
                    new LinkedBlockingQueue<>(MAX_QUEUE_NUM),
                    new NamedThreadFactory("ThreadPoolExecutorFactory-", false),
                    new ThreadPoolExecutor.AbortPolicy());
        }
    }
}

5.靜態(tài)內(nèi)部類實(shí)現(xiàn)線程池工廠(開(kāi)發(fā)中使用的一中方式)

import cn.hutool.core.thread.NamedThreadFactory;
import lombok.NonNull;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 描述:靜態(tài)內(nèi)部類 線程池執(zhí)行器工廠.
 * 1.單例
 * 2.餓漢式+延遲加載
 * @author wangkai
 */
public final class SafeThreadPoolFactory {

    private SafeThreadPoolFactory() {
    }

    /**
     * 全局訪問(wèn)點(diǎn).
     * @param runnable runnable
     */
    public static void execute(@NonNull Runnable runnable) {
        ThreadPoolExecutorHolder.THREAD_POOL_EXECUTOR.execute(runnable);
    }

    /**
     * 靜態(tài)內(nèi)部類創(chuàng)建實(shí)例(單例).
     * 優(yōu)點(diǎn):被調(diào)用時(shí)才會(huì)創(chuàng)建一次實(shí)例
     */
    private static class ThreadPoolExecutorHolder {
        static final int CPU = Runtime.getRuntime().availableProcessors();
        static final int CORE_POOL_SIZE = CPU + 1;
        static final int MAXIMUM_POOL_SIZE = CPU * 2 + 1;
        static final long KEEP_ALIVE_TIME = 1L;
        static final TimeUnit TIME_UNIT = TimeUnit.SECONDS;
        static final int MAX_QUEUE_NUM = 1024;

        //static變量只會(huì)初始化一次
        public static final ThreadPoolExecutor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TIME_UNIT,
                new LinkedBlockingQueue<>(MAX_QUEUE_NUM),
                new NamedThreadFactory("ThreadPoolExecutorFactory-", false),
                new ThreadPoolExecutor.AbortPolicy());
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容