問(wèn)題
java開(kāi)發(fā)中,線程數(shù)通常定義為:
線程數(shù) = Runtime.getRuntime().availableProcessors() * 2, 為什么呢?
前言
在java開(kāi)發(fā)過(guò)程中,不可避免的要使用多線程進(jìn)行開(kāi)發(fā),那么,我們?cè)撊绾未_定創(chuàng)建線程的數(shù)量呢?首先我們先了解幾個(gè)概念
一、線程和進(jìn)程的概念
- 線程和進(jìn)程的區(qū)別:
線程是指程序在執(zhí)行過(guò)程中,能夠執(zhí)行程序代碼的一個(gè)執(zhí)行單元。在java語(yǔ)言中,線程有四種狀態(tài):運(yùn)行 、就緒、掛起和結(jié)束。
進(jìn)程是指一段正在執(zhí)行的程序。而線程有時(shí)也被成為輕量級(jí)的進(jìn)程,他是程序執(zhí)行的最小單元,一個(gè)進(jìn)程可以擁有多個(gè)線程,各個(gè)線程之間共享程序的內(nèi)功空間(代碼段、數(shù)據(jù)段和堆空間)及一些進(jìn)程級(jí)的資源(例如打開(kāi)的文件),但是各個(gè)線程都擁有自己的??臻g。 - 為何要使用多進(jìn)程
在操作系統(tǒng)級(jí)別上來(lái)看主要有以下幾個(gè)方面:
- 使用多線程可以減少程序的響應(yīng)時(shí)間,如果某個(gè)操作和耗時(shí),或者陷入長(zhǎng)時(shí)間的等待,此時(shí)程序?qū)⒉粫?huì)響應(yīng)鼠標(biāo)和鍵盤(pán)等的操作,使用多線程后可以把這個(gè)耗時(shí)的線程分配到一個(gè)單獨(dú)的線程去執(zhí)行,從而使程序具備了更好的交互性。
- 與進(jìn)程相比,線程創(chuàng)建和切換開(kāi)銷(xiāo)更小,同時(shí)多線程在數(shù)據(jù)共享方面效率非常高。
- 多CPU或者多核計(jì)算機(jī)本身就具備執(zhí)行多線程的能力,如果使用單個(gè)進(jìn)程,將無(wú)法重復(fù)利用計(jì)算機(jī)資源,造成資源的巨大浪費(fèi)。在多CPU計(jì)算機(jī)使用多線程能提高CPU的利用率。
- 使用多線程能簡(jiǎn)化程序的結(jié)構(gòu),使程序便于理解和維護(hù)
二、線程的定義
- 線程池中線程的個(gè)數(shù),在《java虛擬機(jī)并發(fā)編程》定義為:
線程數(shù) = cpu可用核心數(shù) / (1-阻塞系數(shù))
其中阻塞系數(shù)的取值在[0,1]之間。計(jì)算密集型任務(wù)的阻塞系數(shù)為0,而IO密集型任務(wù)的阻塞系數(shù)則接近1。一般,我們讓線程執(zhí)行的任務(wù)是比較復(fù)雜的,不會(huì)是單一的計(jì)算密集型任務(wù),或者單一的IO密集型任務(wù),通常會(huì)夾雜著。那么就需要我們?nèi)ビ?jì)算阻塞系數(shù)了。阻塞系數(shù)的定義就是執(zhí)行該任務(wù)阻塞的時(shí)間與(阻塞時(shí)間+計(jì)算時(shí)間)的比值,也就是w/(w+c)。
- 計(jì)算密集型任務(wù)和IO密集型任務(wù)
計(jì)算密集型任務(wù)通常是指需要通過(guò)復(fù)雜的算法來(lái)實(shí)現(xiàn)業(yè)務(wù)邏輯
IO密集型任務(wù)通常是指數(shù)據(jù)庫(kù)數(shù)據(jù)交互、文件上傳下載、網(wǎng)絡(luò)數(shù)據(jù)傳輸?shù)鹊?/li>
三、java中線程數(shù)量創(chuàng)建
1、Java虛擬機(jī)可用的處理器數(shù)
Runtime.getRuntime().availableProcessors()
/**
* Returns the number of processors available to the Java virtual machine.
*
* <p> This value may change during a particular invocation of the virtual
* machine. Applications that are sensitive to the number of available
* processors should therefore occasionally poll this property and adjust
* their resource usage appropriately. </p>
*
* @return the maximum number of processors available to the virtual
* machine; never smaller than one
* @since 1.4
*/
public native int availableProcessors();
2、阻塞系數(shù)計(jì)算
- 可以將你的需要執(zhí)行的任務(wù)量化,你需要確定哪些步驟是IO操作,哪些步驟的計(jì)算操作,然后跑一次,來(lái)確定執(zhí)行這個(gè)任務(wù)耗費(fèi)在IO多少時(shí)間,耗費(fèi)在計(jì)算上多少時(shí)間,這樣算起來(lái)比較麻煩。
- 所以對(duì)于一般的應(yīng)用程序來(lái)說(shuō),每一次任務(wù)都少不了IO和任務(wù)操作,通常可以把阻塞系數(shù)取0.5
最終,我們?cè)賘ava中定義線程數(shù)可以取為:
線程數(shù) = Runtime.getRuntime().availableProcessors() * 2