1. 程式人生 > >根據CPU核心數確定執行緒池併發執行緒數

根據CPU核心數確定執行緒池併發執行緒數

正文

回到頂部

一、丟擲問題

關於如何計算併發執行緒數,一般分兩派,來自兩本書,且都是好書,到底哪個是對的?問題追蹤後,整理如下:

第一派:《Java Concurrency in Practice》即《java併發程式設計實踐》,如下圖:

如上圖,在《Java Concurrency in Practice》一書中,給出了估算執行緒池大小的公式:

Nthreads=Ncpu*Ucpu*(1+w/c),其中

Ncpu=CPU核心數

Ucpu=cpu使用率,0~1

W/C=等待時間與計算時間的比率

第二派:《Programming Concurrency on the JVM Mastering》即《Java 虛擬機器併發程式設計》

執行緒數=Ncpu/(1-阻塞係數)

回到頂部

二.分析

對於派系一,假設cpu100%運轉,即撇開CPU使用率這個因素,執行緒數=Ncpu*(1+w/c)。

現在假設將派系二的公式等於派系一公式,即Ncpu/(1-阻塞係數)=Ncpu*(1+w/c),===》阻塞係數=w/(w+c),即阻塞係數=阻塞時間/(阻塞時間+計算時間),這個結論在派系二後續中得到應徵,如下圖:

由此可見,派系一和派系二其實是一個公式……這樣我就放心了……

回到頂部

三、實際應用

那麼實際使用中併發執行緒數如何設定呢?分析如下(我們以派系一公式為例):

Nthreads=Ncpu*(1+w/c)

IO密集型:一般情況下,如果存在IO,那麼肯定w/c>1(阻塞耗時一般都是計算耗時的很多倍),但是需要考慮系統記憶體有限(每開啟一個執行緒都需要記憶體空間),這裡需要上伺服器測試具體多少個執行緒數適合(CPU佔比、執行緒數、總耗時、記憶體消耗)。如果不想去測試,保守點取1即,Nthreads=Ncpu*(1+1)=2Ncpu。這樣設定一般都OK。

計算密集型:假設沒有等待w=0,則W/C=0. Nthreads=Ncpu。

至此結論就是:

IO密集型=2Ncpu(可以測試後自己控制大小,2Ncpu一般沒問題)(常出現於執行緒中:資料庫資料互動、檔案上傳下載、網路資料傳輸等等)

計算密集型=Ncpu(常出現於執行緒中:複雜演算法)

java中:Ncpu=Runtime.getRuntime().availableProcessors()

=========================此處可略過=============================================

當然派系一種《Java Concurrency in Practice》還有一種說法,

即對於計算密集型的任務,在擁有N個處理器的系統上,當執行緒池的大小為N+1時,通常能實現最優的效率。(即使當計算密集型的執行緒偶爾由於缺失故障或者其他原因而暫停時,這個額外的執行緒也能確保CPU的時鐘週期不會被浪費。)

即,計算密集型=Ncpu+1,但是這種做法導致的多一個cpu上下文切換是否值得,這裡不考慮。讀者可自己考量。

======================================================================

回到頂部

四、總結

選擇執行緒池併發執行緒數的因素很多:任務型別、記憶體等執行緒中使用到所有資源都需要考慮。本文經過對現有文獻的分析論證,得出結論,並給出了實際應用公式,實乃工程師之福利,技術之典範…..

相關推薦

根據CPU核心確定執行併發執行

正文回到頂部一、丟擲問題 關於如何計算併發執行緒數,一般分兩派,來自兩本書,且都是好書,到底哪個是對的?問題追蹤後,整理如下: 第一派:《Java Concurrency in Practice》即《java併發程式設計實踐》,如下圖: 如上圖,在《Java Concurrency in Practice

執行及其執行原理

前言 首先從結構說起 然後執行緒池的引數 最後在結合程式碼簡單分析 new Thread 弊端         第一:每次new Thread 新建物件,效能差         第二

執行原理--執行器AbstractExecutorService

文章目錄 執行緒池原理--執行器AbstractExecutorService AbstractExecutorService Sumit 批量提交任務 執行緒池原理–總索引 執行緒池原理–執行器Ab

執行原理–執行器ExecutorService

文章目錄 執行緒池原理–執行器ExecutorService 相關方法 shutdown submit 批量提交任務 執行緒池原理–總索引 執行緒池原理–執行器Exe

執行原理--執行器Executor

文章目錄 執行緒池原理--執行器Executor 繼承體系 Executor 執行緒池原理–總索引 執行緒池原理–執行器Executor 繼承體系 Executor:一個介面,其定義了

執行原理--執行器ThreadPoolExecutor

文章目錄 執行緒池原理--執行器ThreadPoolExecutor 屬性 構造器 構造器引數介紹 execute()方法 執行緒池原理–總索引 執行緒池原理–執行器Th

執行實現執行的建立 的兩種方法

package cn.itcast.demo5; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /* JDK1.5新特性,實現執行緒池程式 使用

定製在排程執行執行的任務

Java 9併發程式設計指南 目錄 定製在排程執行緒池中執行的任務 準備工作 實現過程 工作原理 擴充套件學習 更多關注 排程執行緒池是Executor框架基本執行緒池的擴充套件,排程在一段時間後執行任務。ScheduledTh

day 34 GIL鎖,執行佇列,執行執行回撥函式

一 . GIL鎖   GIL鎖是python程式碼轉直譯器程式碼的一個鎖         雖然我們加鎖的原因是因為要保護安全性從而降低了效率,但是加鎖也會出現安全性的問題!         二 . 執行緒佇列   import queue   三種佇列形式

什麼是執行執行的工作原理和使用執行的好處

一個執行緒池管理了一組工作執行緒,同時它還包括了一個用於放置等待執行任務的任務佇列(阻塞佇列) 預設情況下,在建立了執行緒池後,執行緒池中的執行緒數為0.當任務提交給執行緒池之後的處理策略如下: 1:如果此時執行緒池中的數量小於corePoolSize(核心池的大小),即

使用執行捕獲執行異常

        在java多執行緒程式中,所有執行緒都不允許丟擲未捕獲的checked exception(比如sleep時的InterruptedException),也就是說各個執行緒需要自己把自己的checked exception處理掉。這一點是通過j

[執行] 關於執行的五種狀態

執行緒狀態 在ThreadPoolExecutor類中定義了執行緒的五種狀態表示,通過AtomicInteger 的高三位來表示執行緒的狀態: private static final int

執行執行相關類

執行緒池概述 系統啟用一個新執行緒的成本是比較高的,因為它涉及與作業系統互動。在這種情形下,使用執行緒池可以很好的提高效能。執行緒池在系統啟動時即建立大量空閒的執行緒,程式將一個Runnable物件或Callable物件傳給執行緒池,執行緒池會啟動一個執行緒來執行它們的run()或call方

定製併發類(六)自定義在計劃的執行執行的任務

宣告:本文是《 Java 7 Concurrency Cookbook 》的第七章, 作者: Javier Fernández González 譯者:鄭玉婷 自定義在計劃的執行緒池內執行的任務 計劃的執行緒池是 Executor 框架的基本執行緒池的擴充套件,允許你定製一個計劃來執行一段時

戲(細)說Executor框架執行任務執行全過程(上)

內容綜述 基於Executor介面中將任務提交和任務執行解耦的設計,ExecutorService和其各種功能強大的實現類提供了非常簡便方式來提交任務並獲取任務執行結果,封裝了任務執行的全部過程。本文嘗試通過對j.u.c.下該部分原始碼的解析以ThreadPoolExecutor為例來追蹤任

戲(細)說Executor框架執行任務執行全過程(下)

上一篇文章中通過引入的一個例子介紹了在Executor框架下,提交一個任務的過程,這個過程就像我們老大的老大要找個老大來執行一個任務那樣簡單。並通過剖析ExecutorService的一種經典實現ThreadPoolExecutor來分析接收任務的主要邏輯,發現ThreadPoolExecu

執行的工作原理與原始碼解讀及各常用執行執行流程圖

有時候花了大把時間去看一些東西卻看不懂,是很 “ 藍瘦 ” 的,花時間也是投資。 本文適合: 曾瞭解過執行緒池卻一直模模糊糊的人 瞭解得差不多卻對某些點依然疑惑的   隨著cpu核數越來越多,不可避免的利用多執行緒技術以充分利用其計算能力。所以,多執

C#中控制執行執行順序

在使用執行緒池時,當用執行緒池執行多個任務時,由於執行的任務時間過長,會導制兩個任務互相執行,如果兩個任務具有一定的操作順序,可能會導制不同的操作結果,這時,就要將執行緒池按順序操作。下面先給一段程式碼,該程式碼是不按順序對執行緒池進行操作的,程式碼如下: using System; using

-1-5 java 多執行緒 概念 程序 執行緒區別聯絡 java建立執行緒方式 執行緒執行緒池概念 執行緒安全 同步 同步程式碼塊 Lock鎖 sleep()和wait()方法的區別 為什麼wait(),notify(),notifyAll()等方法都定義在O

 本文關鍵詞: java 多執行緒 概念 程序 執行緒區別聯絡 java建立執行緒方式 執行緒組 執行緒池概念 執行緒安全 同步 同步程式碼塊 Lock鎖  sleep()和wait()方法的區別 為什麼wait(),notify(),notifyAll()等方法都定義在Object類中 多執行緒

Java多執行程式設計-(7)-使用執行實現執行的複用和一些坑的避免

原文出自 : https://blog.csdn.net/xlgen157387/article/details/78253096 執行緒複用:執行緒池 首先舉個例子: 假設這裡有一個系統,大概每秒需要處理5萬條資料,這5萬條資料為一個批次,而這沒秒傳送的5萬條資料