java?并發(fā)線程個(gè)數(shù)的如何確定
java 并發(fā)線程個(gè)數(shù)的確定
本文從控制變量的角度來談決定線程個(gè)數(shù)的依據(jù)。模型很簡單,在實(shí)際的生產(chǎn)環(huán)境中,情況肯定比下文要復(fù)雜的多。要充分的進(jìn)行測試,以使線程個(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ì)加鎖。對于關(guān)鍵代碼(被頻繁調(diào)用的代碼),往往可以成為線程個(gè)數(shù)的依據(jù)之一。
對于全局鎖(比如static上鎖),無論多少個(gè)線程,代碼都是串行執(zhí)行的。這樣線程越多反而越不好。對于鎖粒度的越小,對于線程并發(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í)間的比率
針對IO密集型的,阻塞耗時(shí)w一般都是計(jì)算耗時(shí)幾倍c,假設(shè)阻塞耗時(shí)=計(jì)算耗時(shí)的情況下,Nthreads=Ncpu*(1+1)=2Ncpu。所以這種情況下,考慮2倍的CPU核心數(shù)做為線程數(shù)
對于計(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)文章
詳解Java?ReentrantReadWriteLock讀寫鎖的原理與實(shí)現(xiàn)
ReentrantReadWriteLock讀寫鎖是使用AQS的集大成者,用了獨(dú)占模式和共享模式。本文和大家一起理解下ReentrantReadWriteLock讀寫鎖的實(shí)現(xiàn)原理,需要的可以了解一下2022-10-10
SpringBoot中定時(shí)任務(wù)的使用方法解析
這篇文章主要介紹了SpringBoot中定時(shí)任務(wù)的使用方法解析,@EnableScheduling?注解,它的作用是發(fā)現(xiàn)注解?@Scheduled的任務(wù)并由后臺(tái)執(zhí)行,沒有它的話將無法執(zhí)行定時(shí)任務(wù),需要的朋友可以參考下2024-01-01
SpringBoot配置文件中數(shù)據(jù)庫密碼加密兩種方案(推薦)
SpringBoot項(xiàng)目經(jīng)常將連接數(shù)據(jù)庫的密碼明文放在配置文件里,安全性就比較低一些,尤其在一些企業(yè)對安全性要求很高,因此我們就考慮如何對密碼進(jìn)行加密,文中給大家介紹加密的兩種方式,感興趣的朋友一起看看吧2019-10-10
在Java生產(chǎn)環(huán)境下進(jìn)行性能監(jiān)控與調(diào)優(yōu)的詳細(xì)過程
在Java生產(chǎn)環(huán)境下進(jìn)行性能監(jiān)控與調(diào)優(yōu)是一個(gè)復(fù)雜但重要的過程,它涉及到多個(gè)方面,包括代碼分析、JVM監(jiān)控、線程管理、垃圾收集優(yōu)化、內(nèi)存管理、數(shù)據(jù)庫交互等,下面我將提供一個(gè)詳細(xì)的概述和示例代碼,需要的朋友可以參考下2025-02-02
Spring框架實(shí)現(xiàn)AOP添加日志記錄功能過程詳解
這篇文章主要介紹了Spring框架實(shí)現(xiàn)AOP添加日志記錄功能過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
IntelliJ IDEA基于SpringBoot如何搭建SSM開發(fā)環(huán)境的步驟詳解
這篇文章主要介紹了IntelliJ IDEA基于SpringBoot如何搭建SSM開發(fā)環(huán)境,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10
在java中實(shí)現(xiàn)C#語法里的按引用傳遞參數(shù)的方法
下面小編就為大家?guī)硪黄趈ava中實(shí)現(xiàn)C#語法里的按引用傳遞參數(shù)的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09

