溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何進(jìn)行線程池配置與數(shù)據(jù)庫(kù)連接池最大連接數(shù)配置

發(fā)布時(shí)間:2021-12-02 14:37:02 來源:億速云 閱讀:1011 作者:柒染 欄目:大數(shù)據(jù)

如何進(jìn)行線程池配置與數(shù)據(jù)庫(kù)連接池最大連接數(shù)配置,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。

線程池 相關(guān)配置,不僅平時(shí)經(jīng)常用到,而且面試也會(huì)經(jīng)常問到。

如何設(shè)置線程池大?。?/h4>

CPU 密集型任務(wù):這種任務(wù)消耗的主要是 CPU 資源,可以將線程數(shù)設(shè)置為 N(CPU 核心數(shù))+1,比 CPU 核心數(shù)多出來的一個(gè)線程是為了防止線程偶發(fā)的缺頁(yè)中斷,或者其它原因?qū)е碌娜蝿?wù)暫停而帶來的影響。一旦任務(wù)暫停,CPU 就會(huì)處于空閑狀態(tài),而在這種情況下多出來的一個(gè)線程就可以充分利用 CPU 的空閑時(shí)間。

I/O 密集型任務(wù):這種任務(wù)應(yīng)用起來,系統(tǒng)會(huì)用大部分的時(shí)間來處理 I/O 交互,而線程在處理 I/O 的時(shí)間段內(nèi)不會(huì)占用 CPU 來處理,這時(shí)就可以將 CPU 交出給其它線程使用。因此在 I/O 密集型任務(wù)的應(yīng)用中,我們可以多配置一些線程,具體的計(jì)算方法是 2N。

綜上可知:當(dāng)線程數(shù)量太小,同一時(shí)間大量請(qǐng)求將被阻塞在線程隊(duì)列中排隊(duì)等待執(zhí)行線程,此時(shí) CPU 沒有得到充分利用;當(dāng)線程數(shù)量太大,被創(chuàng)建的執(zhí)行線程同時(shí)在爭(zhēng)取 CPU 資源,又會(huì)導(dǎo)致大量的上下文切換,從而增加線程的執(zhí)行時(shí)間,影響了整體執(zhí)行效率。通過測(cè)試可知,4~6 個(gè)線程數(shù)是最合適的。

public ThreadPoolExecutor(int corePoolSize,//線程池的核心線程數(shù)量
int maximumPoolSize,//線程池的最大線程數(shù)
long keepAliveTime,//當(dāng)線程數(shù)大于核心線程數(shù)時(shí),多余的空閑線程存活的最長(zhǎng)時(shí)間
TimeUnit unit,//時(shí)間單位
BlockingQueue<Runnable> workQueue,//任務(wù)隊(duì)列,用來儲(chǔ)存等待執(zhí)行任務(wù)的隊(duì)列
ThreadFactory threadFactory,//線程工廠,用來創(chuàng)建線程,一般默認(rèn)即可
RejectedExecutionHandler handler) //拒絕策略,當(dāng)提交的任務(wù)過多而不能及時(shí)處理時(shí),我們可以定制策略來處理任務(wù)

如何進(jìn)行線程池配置與數(shù)據(jù)庫(kù)連接池最大連接數(shù)配置

如何進(jìn)行線程池配置與數(shù)據(jù)庫(kù)連接池最大連接數(shù)配置 

但是某些號(hào)稱XXX架構(gòu)師配置線程池參數(shù)(或者jdbc連接池?cái)?shù)量)還是會(huì)拍腦袋,隨便定個(gè) 核心線程數(shù)或者最大線程數(shù)100 

這就是沒有性能意思的碼農(nóng)(估計(jì)都了解過怎么配置,就是沒有在意)了。 雖然說配置比如 最大線程數(shù)100 , 其實(shí)對(duì)于并發(fā)量不大的項(xiàng)目來說,其實(shí)運(yùn)行起來也不會(huì)出什么問題。但是 能改則改。

// CPU 核心數(shù):// 核數(shù)  。 CPU 密集計(jì)算: N+1//  IO 類型的就是: 2Nint cores = Runtime.getRuntime().availableProcessors();

線程池 spring boot 異步執(zhí)行任務(wù)配置實(shí)例, 一般都是CPU類型的異步任務(wù)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定義異步線程的執(zhí)行器
 * 使用 ThreadPoolTaskExecutor 線程池方式,避免開啟過多的線程
 *
 * @author James
 * @date 2018/7/16 上午11:40
 */
@Configuration
@EnableAsync
public class ExecutorConfig
{

    /**
     * Set the ThreadPoolExecutor's core pool size.
     */
    private int corePoolSize = 4;

    /**
     * Set the ThreadPoolExecutor's maximum pool size.
     */
    private int maxPoolSize = Runtime.getRuntime().availableProcessors() + 3;

    /**
     * Set the capacity for the ThreadPoolExecutor's BlockingQueue.
     * 隊(duì)列數(shù)不能太大,否則就會(huì)任務(wù)堆積,處理就太慢了。
     */
    private int queueCapacity = 300;

    @Bean
    public Executor myAsync()
    {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setThreadNamePrefix("MyExecutor-");

        // rejection-policy:當(dāng)pool已經(jīng)達(dá)到max size的時(shí)候,如何處理新任務(wù)
        // CALLER_RUNS:不在新線程中執(zhí)行任務(wù),而是有調(diào)用者所在的線程來執(zhí)行 。 一般這種任務(wù)不能丟棄
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }
}

以上代碼就是 當(dāng)spring boot 中 執(zhí)行 異步 代碼的時(shí)候所用到的線程池配置了: 即加了 @Async 的方法

自定義CPU密集型線程池例子

使用 LinkedBlockingQueue 是因?yàn)槠淇梢杂懈叩耐掏铝?/p>

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.concurrent.*;

@Component
public class ExecutionResultPool {

    private static final Logger logger = LoggerFactory.getLogger(ExecutionResultPool.class);

    private ExecutorService threadPool;

    public void init() {

        // 核數(shù)  。 CPU 密集計(jì)算: N+1
        //  IO 類型的就是: 2N
        int cores = Runtime.getRuntime().availableProcessors();

        ThreadFactory threadFactory = new ThreadFactoryBuilder()
                .setNameFormat("timing-executor-pool-%d").build();
        threadPool = new ThreadPoolExecutor(4,
                cores+3, 30, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000),
                threadFactory,
                (r, executor) -> {
                    try {
                        //  // 嘗試再次加入隊(duì)列。如果隊(duì)列已滿,那么等待,直到隊(duì)列空了就放進(jìn)去
                        executor.getQueue().put(r);
                    } catch (InterruptedException e) {
                        logger.error("任務(wù)加入隊(duì)列失敗", e);
                        Thread.currentThread().interrupt();
                    }
                });
        logger.info("初始化任務(wù)執(zhí)行線程池 {}", threadFactory);
    }

    public void execute(Runnable runnable) {
        threadPool.execute(runnable);
    }

}

關(guān)于如何進(jìn)行線程池配置與數(shù)據(jù)庫(kù)連接池最大連接數(shù)配置問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI