本篇內容主要講解“java并發線程個數的怎么確定”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“java并發線程個數的怎么確定”吧!
本文從控制變量的角度來談決定線程個數的依據。模型很簡單,在實際的生產環境中,情況肯定比下文要復雜的多。要充分的進行測試,以使線程個數為優。
java應用程序大概分為兩種:cpu密集型和io密集型。
就是指線程大部分時間都在用cpu,一般來說,普通的操作都需要用到cpu,比如計算,讀取,循環,賦值,查詢,排序等等。在最理想的情況下,大牛們建議將線程數設置為count(cpu)+-1
io操作一般不需要cpu的參與,線程在io時,線程會被阻塞(線程的六個狀態之一就有Blocked)如果一個線程完成某項工作一共需要100ms,其中io需要80ms,cpu需要20ms(忽略其他時間).那么線程數應該設立為5.
多線程為了安全,往往會加鎖。對于關鍵代碼(被頻繁調用的代碼),往往可以成為線程個數的依據之一。
對于全局鎖(比如static上鎖),無論多少個線程,代碼都是串行執行的。這樣線程越多反而越不好。對于鎖粒度的越小,對于線程并發來說越有利。比如ConcurrentHashMap來說,分了16個segment,也就是加了16把鎖。
在理性的情況下,鎖粒度可以降低16倍,那么自然可以允許16個并發。最壞的情況是16個線程去爭用一個segment。這個線程的個數需要根據實際情況去調優。
因為服務器是擁有多個處理器核心的。運行某進程時,如果只有一個線程,則只能調動一個處理器核心,其他處理器核心可能處于空閑狀態。如果是多線程,則可以調用多個處理器核心,用最大效率去處理任務。
創建線程池一般需要參數有:核心線程數,最大線程數,線程銷毀時間,任務隊列,拒絕策略等。
線程池里的線程分為兩種,分別是核心線程和非核心線程。當線程池接收到任務時,會先創建核心線程數去處理任務,直至待處理的任務數量超過任務隊列長度和核心線程數之和時,會繼續創建非核心線程直至最大線程數。
線程池接收到的任務數量在即將超過任務隊列長度和最大線程數之和時,會觸發拒絕策略處理該任務。
非核心線程在執行完成后會立即銷毀,核心線程則會等待設置的銷毀時間后再進行銷毀。
當任務隊列長度足夠大時,核心線程數和最大線程數相等,不然不能觸發到創建非核心線程
線程數計算公式為:
Nthreads=NcpuUcpu(1+w/c) =Ncpu*(1+w/c)
其中 Nthreads:線程數;Ncpu:處理器核心數;Ucpu:處理器的使用百分比;W/C:等待時間與計算時間的比率
Ncpu可以通過以下代碼獲取
Runtime.getRuntime().availableProcessors()
等待時間與計算時間的比率
針對IO密集型的,阻塞耗時w一般都是計算耗時幾倍c,假設阻塞耗時=計算耗時的情況下,Nthreads=Ncpu*(1+1)=2Ncpu。所以這種情況下,考慮2倍的CPU核心數做為線程數
對于計算密集型的,阻塞耗時趨于0,即w/c趨于0,公式Nthreads = Ncpu。
線程數一般是處理器核心數的整數倍。線程數設置過多,在多任務并發情況下,則會影響服務器的整體運行速度;設置過少,則不能最大化應用服務器性能。所以需要根據具體業務來具體調整。
到此,相信大家對“java并發線程個數的怎么確定”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。