您好,登錄后才能下訂單哦!
如何進行線程池配置與數據庫連接池最大連接數配置,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
線程池 相關配置,不僅平時經常用到,而且面試也會經常問到。
CPU 密集型任務:這種任務消耗的主要是 CPU 資源,可以將線程數設置為 N(CPU 核心數)+1,比 CPU 核心數多出來的一個線程是為了防止線程偶發的缺頁中斷,或者其它原因導致的任務暫停而帶來的影響。一旦任務暫停,CPU 就會處于空閑狀態,而在這種情況下多出來的一個線程就可以充分利用 CPU 的空閑時間。
I/O 密集型任務:這種任務應用起來,系統會用大部分的時間來處理 I/O 交互,而線程在處理 I/O 的時間段內不會占用 CPU 來處理,這時就可以將 CPU 交出給其它線程使用。因此在 I/O 密集型任務的應用中,我們可以多配置一些線程,具體的計算方法是 2N。
綜上可知:當線程數量太小,同一時間大量請求將被阻塞在線程隊列中排隊等待執行線程,此時 CPU 沒有得到充分利用;當線程數量太大,被創建的執行線程同時在爭取 CPU 資源,又會導致大量的上下文切換,從而增加線程的執行時間,影響了整體執行效率。通過測試可知,4~6 個線程數是最合適的。
public ThreadPoolExecutor(int corePoolSize,//線程池的核心線程數量 int maximumPoolSize,//線程池的最大線程數 long keepAliveTime,//當線程數大于核心線程數時,多余的空閑線程存活的最長時間 TimeUnit unit,//時間單位 BlockingQueue<Runnable> workQueue,//任務隊列,用來儲存等待執行任務的隊列 ThreadFactory threadFactory,//線程工廠,用來創建線程,一般默認即可 RejectedExecutionHandler handler) //拒絕策略,當提交的任務過多而不能及時處理時,我們可以定制策略來處理任務
但是某些號稱XXX架構師配置線程池參數(或者jdbc連接池數量)還是會拍腦袋,隨便定個 核心線程數或者最大線程數100
這就是沒有性能意思的碼農(估計都了解過怎么配置,就是沒有在意)了。 雖然說配置比如 最大線程數100 , 其實對于并發量不大的項目來說,其實運行起來也不會出什么問題。但是 能改則改。
// CPU 核心數:// 核數 。 CPU 密集計算: N+1// IO 類型的就是: 2Nint cores = Runtime.getRuntime().availableProcessors();
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; /** * 自定義異步線程的執行器 * 使用 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. * 隊列數不能太大,否則就會任務堆積,處理就太慢了。 */ 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:當pool已經達到max size的時候,如何處理新任務 // CALLER_RUNS:不在新線程中執行任務,而是有調用者所在的線程來執行 。 一般這種任務不能丟棄 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } }
以上代碼就是 當spring boot 中 執行 異步 代碼的時候所用到的線程池配置了: 即加了 @Async 的方法
使用 LinkedBlockingQueue 是因為其可以有更高的吞吐量
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() { // 核數 。 CPU 密集計算: 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 { // // 嘗試再次加入隊列。如果隊列已滿,那么等待,直到隊列空了就放進去 executor.getQueue().put(r); } catch (InterruptedException e) { logger.error("任務加入隊列失敗", e); Thread.currentThread().interrupt(); } }); logger.info("初始化任務執行線程池 {}", threadFactory); } public void execute(Runnable runnable) { threadPool.execute(runnable); } }
關于如何進行線程池配置與數據庫連接池最大連接數配置問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。