CPU核心數(shù),線程數(shù)
CPU個(gè)數(shù)、核心數(shù)、線程數(shù)的關(guān)系:
- CPU個(gè)數(shù):是指物理上,即硬件上的核心數(shù);
- 核心數(shù):是邏輯上的,簡(jiǎn)單理解為邏輯上模擬出的核心數(shù);
- 線程數(shù):是同一時(shí)刻設(shè)備能并行執(zhí)行的程序個(gè)數(shù),線程數(shù) = cpu個(gè)數(shù) * 核數(shù);
CPU線程數(shù)和Java多線程概念:
- 單個(gè)CPU線程在同一時(shí)刻只能執(zhí)行單一Java程序,也就是一個(gè)線程
- 單個(gè)線程同時(shí)只能在單個(gè)CPU線程中執(zhí)行
- 線程是操作系統(tǒng)最小的調(diào)度單位,進(jìn)程是資源(比如:內(nèi)存)分配的最小單位
- Java中的所有線程在JVM進(jìn)程中,CPU調(diào)度的是進(jìn)程中的線程
- Java多線程并不是由于CPU線程數(shù)為多個(gè)才稱為多線程,當(dāng)Java線程數(shù)大于CPU線程數(shù),操作系統(tǒng)使用時(shí)間片機(jī)制,采用線程調(diào)度算法,頻繁的進(jìn)行線程切換。
IO阻塞時(shí),線程會(huì)釋放CPU嗎?
當(dāng)線程處于IO操作時(shí),線程是阻塞的,線程由運(yùn)行狀態(tài)切換到等待狀態(tài)。此時(shí)CPU會(huì)做上下文切換,以便處理其他程序;當(dāng)IO操作完成后,CPU會(huì)收到一個(gè)來(lái)自硬盤(pán)的中斷信號(hào),CPU正在執(zhí)行的線程因此會(huì)被打斷,回到ready隊(duì)列。而先前因I/O而waiting的線程隨著I/O的完成也再次回到就緒隊(duì)列,此時(shí)CPU可能會(huì)選擇他執(zhí)行。
JAVA中并發(fā)和并行的概念
- 并行:指兩個(gè)或多個(gè)事件在同一時(shí)刻點(diǎn)發(fā)生,CPU同時(shí)執(zhí)行;
- 并發(fā):指兩個(gè)或多個(gè)事件在同一時(shí)間段內(nèi)發(fā)生,CPU交替執(zhí)行;
JAVA線程可以同時(shí)在多個(gè)核上運(yùn)行嗎?(思考)
操作系統(tǒng)是基于線程調(diào)度的,在同一時(shí)刻,JAVA進(jìn)程中不同的線程可能會(huì)在不同的核上并行運(yùn)行。
線程是調(diào)度的最小單位,而進(jìn)程是資源(比如:內(nèi)存)分配的最小單位。
時(shí)間片輪轉(zhuǎn)機(jī)制
時(shí)間片輪轉(zhuǎn)法(Round-Robin,RR):
根據(jù)先進(jìn)先出原則,排成隊(duì)列(就緒隊(duì)列),調(diào)度時(shí),將CPU分配給隊(duì)首進(jìn)程,讓其執(zhí)行一個(gè)時(shí)間段(稱為:時(shí)間片),時(shí)間片通常為10-100ms數(shù)量級(jí),當(dāng)執(zhí)行的時(shí)間片用完時(shí),會(huì)由計(jì)時(shí)器發(fā)出時(shí)鐘中斷請(qǐng)求,調(diào)度程序便據(jù)此來(lái)停止該進(jìn)程的執(zhí)行,并將它排到隊(duì)列末尾,然后再把CPU重新分配給當(dāng)前隊(duì)列的隊(duì)首進(jìn)程,同理如此往復(fù)。
時(shí)間片大小取決于:
- 系統(tǒng)對(duì)響應(yīng)時(shí)間的要求
- 就緒隊(duì)列中進(jìn)程的數(shù)目
- 系統(tǒng)的處理能力
進(jìn)程調(diào)度
采用此算法的系統(tǒng),其程序就緒隊(duì)列往往按進(jìn)程到達(dá)的時(shí)間來(lái)排序。進(jìn)程調(diào)度程序總是選擇就緒隊(duì)列中的第一個(gè)進(jìn)程,也就是說(shuō)按照先來(lái)先服務(wù)原則調(diào)度,但一旦進(jìn)程占用處理機(jī)則僅使用一個(gè)時(shí)間片。在使用一個(gè)時(shí)間片后,進(jìn)程還沒(méi)有完成其運(yùn)行,它必須釋放出處理機(jī)給下一個(gè)就緒的進(jìn)程,而被搶占的進(jìn)程返回到就緒隊(duì)列的末尾重新排隊(duì)等待再次運(yùn)行。
處理器同一個(gè)時(shí)間只能處理一個(gè)任務(wù)。處理器在處理多任務(wù)的時(shí)候,就要看請(qǐng)求的時(shí)間順序,如果時(shí)間一致,就要進(jìn)行預(yù)測(cè)。挑到一個(gè)任務(wù)后,需要若干步驟才能做完,這些步驟中有些需要處理器參與,有些不需要(如磁盤(pán)控制器的存儲(chǔ)過(guò)程)。不需要處理器處理的時(shí)候,這部分時(shí)間就要分配給其他的進(jìn)程。原來(lái)的進(jìn)程就要處于等待的時(shí)間段上。經(jīng)過(guò)周密分配時(shí)間,宏觀上就象是多個(gè)任務(wù)一起運(yùn)行一樣,但微觀上是有先后的,就是時(shí)間片輪換。
實(shí)現(xiàn)思想
時(shí)間片輪轉(zhuǎn)算法的基本思想是,系統(tǒng)將所有的就緒進(jìn)程按先來(lái)先服務(wù)算法的原則,排成一個(gè)隊(duì)列,每次調(diào)度時(shí),系統(tǒng)把處理機(jī)分配給隊(duì)列首進(jìn)程,并讓其執(zhí)行一個(gè)時(shí)間片。當(dāng)執(zhí)行的時(shí)間片用完時(shí),由一個(gè)計(jì)時(shí)器發(fā)出時(shí)鐘中斷請(qǐng)求,調(diào)度程序根據(jù)這個(gè)請(qǐng)求停止該進(jìn)程的運(yùn)行,將它送到就緒隊(duì)列的末尾,再把處理機(jī)分給就緒隊(duì)列中新的隊(duì)列首進(jìn)程,同時(shí)讓它也執(zhí)行一個(gè)時(shí)間片
Java調(diào)度機(jī)制
所有的Java虛擬機(jī)都有一個(gè)線程調(diào)度器,用來(lái)確定那個(gè)時(shí)刻運(yùn)行那個(gè)線程。主要包含兩種:搶占式線程調(diào)度器和協(xié)作式線程調(diào)度器。
- 搶占式線程調(diào)度:每個(gè)線程可能會(huì)有自己的優(yōu)先級(jí),但是優(yōu)先及并不意味著高優(yōu)先級(jí)的線程一定會(huì)被調(diào)度,而是由CPU隨機(jī)的選擇,所謂搶占式的線程調(diào)度,就是說(shuō)一個(gè)線程在執(zhí)行自己的任務(wù)時(shí),雖然任務(wù)還沒(méi)有執(zhí)行完,但是CPU會(huì)迫使它暫停,讓其它線程占有CPU的使用權(quán)。
- 協(xié)作式線程調(diào)度:每個(gè)線程可以有自己的優(yōu)先級(jí),但優(yōu)先級(jí)并不意味著高優(yōu)先級(jí)的線程一定會(huì)被最先調(diào)度,而是由cpu時(shí)機(jī)選擇的,所謂協(xié)作式的線程調(diào)度,就是說(shuō)一個(gè)線程在執(zhí)行自己的任務(wù)時(shí),不允許被中途打斷,一定等當(dāng)前線程將任務(wù)執(zhí)行完畢后才會(huì)釋放對(duì)cpu的占有,其它線程才可以搶占該cpu。
兩者對(duì)比:
搶占式線程調(diào)度不易發(fā)生饑餓現(xiàn)象,不易因?yàn)橐粋€(gè)線程的問(wèn)題而影響整個(gè)進(jìn)程的執(zhí)行,但是其頻繁阻塞與調(diào)度,會(huì)造成系統(tǒng)資源的浪費(fèi)。協(xié)作式的線程調(diào)度很容易因?yàn)橐粋€(gè)線程的問(wèn)題導(dǎo)致整個(gè)進(jìn)程中其它線程饑餓。
總結(jié):
- Java在調(diào)度機(jī)制上采用的是搶占式的線程調(diào)度機(jī)制。
- Java線程在運(yùn)行的過(guò)程中多個(gè)線程之間式協(xié)作式的。