Java中如何正確的創(chuàng)建線程數(shù)量

問(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)程的概念
  1. 線程和進(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。
  2. 為何要使用多進(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ù)
二、線程的定義
  1. 線程池中線程的個(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)。

  1. 計(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
希望對(duì)你有所幫助
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容