java?并發(fā)線程個(gè)數(shù)的如何確定
java 并發(fā)線程個(gè)數(shù)的確定
本文從控制變量的角度來談決定線程個(gè)數(shù)的依據(jù)。模型很簡單,在實(shí)際的生產(chǎn)環(huán)境中,情況肯定比下文要復(fù)雜的多。要充分的進(jìn)行測(cè)試,以使線程個(gè)數(shù)為優(yōu)。
java應(yīng)用程序大概分為兩種:cpu密集型和io密集型。
cpu密集型
就是指線程大部分時(shí)間都在用cpu,一般來說,普通的操作都需要用到cpu,比如計(jì)算,讀取,循環(huán),賦值,查詢,排序等等。在最理想的情況下,大牛們建議將線程數(shù)設(shè)置為count(cpu)+-1
io密集型
io操作一般不需要cpu的參與,線程在io時(shí),線程會(huì)被阻塞(線程的六個(gè)狀態(tài)之一就有Blocked)如果一個(gè)線程完成某項(xiàng)工作一共需要100ms,其中io需要80ms,cpu需要20ms(忽略其他時(shí)間).那么線程數(shù)應(yīng)該設(shè)立為5.
有鎖的情況
多線程為了安全,往往會(huì)加鎖。對(duì)于關(guān)鍵代碼(被頻繁調(diào)用的代碼),往往可以成為線程個(gè)數(shù)的依據(jù)之一。
對(duì)于全局鎖(比如static上鎖),無論多少個(gè)線程,代碼都是串行執(zhí)行的。這樣線程越多反而越不好。對(duì)于鎖粒度的越小,對(duì)于線程并發(fā)來說越有利。比如ConcurrentHashMap來說,分了16個(gè)segment,也就是加了16把鎖。
在理性的情況下,鎖粒度可以降低16倍,那么自然可以允許16個(gè)并發(fā)。最壞的情況是16個(gè)線程去爭用一個(gè)segment。這個(gè)線程的個(gè)數(shù)需要根據(jù)實(shí)際情況去調(diào)優(yōu)。
java 線程池線程數(shù)量確定思路
多線程可以快速執(zhí)行任務(wù)的原理
因?yàn)榉?wù)器是擁有多個(gè)處理器核心的。運(yùn)行某進(jìn)程時(shí),如果只有一個(gè)線程,則只能調(diào)動(dòng)一個(gè)處理器核心,其他處理器核心可能處于空閑狀態(tài)。如果是多線程,則可以調(diào)用多個(gè)處理器核心,用最大效率去處理任務(wù)。
創(chuàng)建線程池需要的參數(shù)
創(chuàng)建線程池一般需要參數(shù)有:核心線程數(shù),最大線程數(shù),線程銷毀時(shí)間,任務(wù)隊(duì)列,拒絕策略等。
線程池里的線程分為兩種,分別是核心線程和非核心線程。當(dāng)線程池接收到任務(wù)時(shí),會(huì)先創(chuàng)建核心線程數(shù)去處理任務(wù),直至待處理的任務(wù)數(shù)量超過任務(wù)隊(duì)列長度和核心線程數(shù)之和時(shí),會(huì)繼續(xù)創(chuàng)建非核心線程直至最大線程數(shù)。
線程池接收到的任務(wù)數(shù)量在即將超過任務(wù)隊(duì)列長度和最大線程數(shù)之和時(shí),會(huì)觸發(fā)拒絕策略處理該任務(wù)。
非核心線程在執(zhí)行完成后會(huì)立即銷毀,核心線程則會(huì)等待設(shè)置的銷毀時(shí)間后再進(jìn)行銷毀。
當(dāng)任務(wù)隊(duì)列長度足夠大時(shí),核心線程數(shù)和最大線程數(shù)相等,不然不能觸發(fā)到創(chuàng)建非核心線程
確定線程數(shù)
線程數(shù)計(jì)算公式為:
Nthreads=NcpuUcpu(1+w/c) =Ncpu*(1+w/c)
其中 Nthreads:線程數(shù);Ncpu:處理器核心數(shù);Ucpu:處理器的使用百分比;W/C:等待時(shí)間與計(jì)算時(shí)間的比率
Ncpu可以通過以下代碼獲取
Runtime.getRuntime().availableProcessors()
等待時(shí)間與計(jì)算時(shí)間的比率
針對(duì)IO密集型的,阻塞耗時(shí)w一般都是計(jì)算耗時(shí)幾倍c,假設(shè)阻塞耗時(shí)=計(jì)算耗時(shí)的情況下,Nthreads=Ncpu*(1+1)=2Ncpu。所以這種情況下,考慮2倍的CPU核心數(shù)做為線程數(shù)
對(duì)于計(jì)算密集型的,阻塞耗時(shí)趨于0,即w/c趨于0,公式Nthreads = Ncpu。
線程數(shù)一般是處理器核心數(shù)的整數(shù)倍。線程數(shù)設(shè)置過多,在多任務(wù)并發(fā)情況下,則會(huì)影響服務(wù)器的整體運(yùn)行速度;設(shè)置過少,則不能最大化應(yīng)用服務(wù)器性能。所以需要根據(jù)具體業(yè)務(wù)來具體調(diào)整。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring中@Transactional用法詳細(xì)介紹
這篇文章主要介紹了Spring中@Transactional用法詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下2017-02-02java中instanceof 關(guān)鍵字作用和實(shí)際用途詳解
這篇文章主要介紹了java中instanceof 關(guān)鍵字作用和實(shí)際用途,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04java實(shí)現(xiàn)Xml與json之間的相互轉(zhuǎn)換操作示例
這篇文章主要介紹了java實(shí)現(xiàn)Xml與json之間的相互轉(zhuǎn)換操作,結(jié)合實(shí)例形式分析了Java xml與json相互轉(zhuǎn)換工具類的定義與使用相關(guān)操作技巧,需要的朋友可以參考下2019-06-06java使用篩選法求n以內(nèi)的素?cái)?shù)示例(java求素?cái)?shù))
這篇文章主要介紹了java使用篩選法求n以內(nèi)的素?cái)?shù)示例(java求素?cái)?shù)),需要的朋友可以參考下2014-04-04一個(gè)簡單的java學(xué)生寢室查詢系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了一個(gè)簡單的java學(xué)生寢室查詢系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10java web開發(fā)之servlet圖形驗(yàn)證碼功能的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了java web開發(fā)之servlet中圖形驗(yàn)證碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11java構(gòu)造函數(shù)的三種類型總結(jié)
在本篇文章里小編給大家整理了一篇關(guān)于java構(gòu)造函數(shù)的三種類型總結(jié)內(nèi)容,有需要的朋友們可以學(xué)習(xí)參考下。2021-01-01Java學(xué)習(xí)之Lambda表達(dá)式的使用詳解
Lambda表達(dá)式是Java SE 8中一個(gè)重要的新特性,允許通過表達(dá)式來代替功能接口。本文將通過一些簡單的示例和大家講講Lamda表達(dá)式的使用,感興趣的可以了解一下2022-12-12