新聞中心
前言
大家好,一直以來(lái)我都本著用最通俗的話理解核心的知識(shí)點(diǎn), 我認(rèn)為所有的難點(diǎn)都離不開(kāi) 「基礎(chǔ)知識(shí)」 的鋪墊。目前正在出一個(gè)Java多線程專題長(zhǎng)期系列教程,從入門到進(jìn)階, 篇幅會(huì)較多, 喜歡的話,給個(gè)關(guān)注? ~

適合人群
- 有一定的Java基礎(chǔ)。
- 想學(xué)習(xí)或了解多線程開(kāi)發(fā)。
- 想提高自己的同學(xué)。
背景
之前給大家講了一些框架的使用,這些都屬于業(yè)務(wù)層面的東西,你需要熟練掌握它并在項(xiàng)目中會(huì)運(yùn)用它即可,但這些對(duì)自身技術(shù)的積累是遠(yuǎn)遠(yuǎn)不夠的,如果你想要提高自己,對(duì)于語(yǔ)言本身你需要花更多的時(shí)間去挖掘而不是局限于框架的使用,所以之前為什么跟大家一直強(qiáng)調(diào)基礎(chǔ)的重要性,框架可以千變?nèi)f化,層出不窮,但是基礎(chǔ)它是不變的,不管是學(xué)java還是前端或者是其它語(yǔ)言, 這一點(diǎn)大家還是需要認(rèn)清的。
接下來(lái)的幾期會(huì)專門講多線程這一塊,篇幅會(huì)較多,耐心看完你一定會(huì)有收獲~
情景回顧
之前有給大家講過(guò)Java的基礎(chǔ)和進(jìn)階部分,如果這方面還薄弱的同學(xué),可以到底部查看往期教程。那時(shí)本來(lái)想把多線程也出一些教程,但是可能對(duì)于大家會(huì)有點(diǎn)難度,特別是剛?cè)腴T的同學(xué),而且這方面的知識(shí)又比較多。或許平時(shí)項(xiàng)目開(kāi)發(fā),只是用用框架或者直接使用框架提供的一些多線程方法,很少會(huì)自己手寫(xiě),即便這樣,還是需要深入學(xué)習(xí)的,因?yàn)槊嬖嚨臅r(shí)候,這個(gè)地方幾乎是必問(wèn)的,而且對(duì)于自身的提高還是有幫助的。
今天我們不涉及代碼部分,先帶著大家過(guò)一遍理論,一起來(lái)看一下什么是線程和進(jìn)程 ~
什么是進(jìn)程
在講之前,先給大家講一下,在早期,計(jì)算機(jī)是如何工作的。
在很早以前,計(jì)算機(jī)都是通過(guò)一個(gè)個(gè)指令去工作的,用戶輸入一個(gè)指令,計(jì)算機(jī)完成一個(gè)操作,這種效率是很低的。因?yàn)檩斎胍粋€(gè)指令,計(jì)算機(jī)就等待。后來(lái)人們引入了批量處理,將一系列指令交給計(jì)算機(jī)處理,但是這個(gè)過(guò)程仍然是串行的,內(nèi)部執(zhí)行還是會(huì)阻塞。隨著時(shí)間的發(fā)展,人們對(duì)于計(jì)算機(jī)的性能要求越來(lái)越高,因?yàn)闀r(shí)間就是金錢,如果能提高效率,老板當(dāng)然高興了~
后來(lái),人們就提出了計(jì)算機(jī)進(jìn)程的概念, 我們先看一下百科中是如何描述進(jìn)程的:
進(jìn)程(Process)是計(jì)算機(jī)中的程序關(guān)于某數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的基本單位,是操作系統(tǒng)結(jié)構(gòu)的基礎(chǔ)。在早期面向進(jìn)程設(shè)計(jì)的計(jì)算機(jī)結(jié)構(gòu)中,進(jìn)程是程序的基本執(zhí)行實(shí)體
這里,仍然不給大家提線程的概念,我們接著看進(jìn)程。我們從中可以得到一個(gè)核心點(diǎn),它是計(jì)算機(jī)系統(tǒng)資源分配和調(diào)度的基本單位。那么它又是怎么去分配和調(diào)度的呢?
上下文切換
當(dāng)程序通過(guò)某種手段(編程語(yǔ)言編寫(xiě))被編譯為一系列指令和數(shù)據(jù)集合后,此時(shí),CPU采用時(shí)間片輪轉(zhuǎn)的方式運(yùn)行進(jìn)程。CPU為每個(gè)進(jìn)程分配一個(gè)時(shí)間段,稱作它的時(shí)間片。如果在時(shí)間片結(jié)束時(shí)進(jìn)程還在運(yùn)行,則暫停這個(gè)進(jìn)程的運(yùn)行,并且CPU分配給另一個(gè)進(jìn)程(這個(gè)過(guò)程叫做上下文切換)。如果進(jìn)程在時(shí)間片結(jié)束前阻塞或結(jié)束,則CPU立即進(jìn)行切換,不用等待時(shí)間片用完。
當(dāng)進(jìn)程暫停時(shí),它會(huì)保存當(dāng)前進(jìn)程的狀態(tài)(進(jìn)程標(biāo)識(shí),進(jìn)程使用的資源等),在下一次切換回來(lái)時(shí)根據(jù)之前保存的狀態(tài)進(jìn)行恢復(fù),接著繼續(xù)執(zhí)行。
使用進(jìn)程和CPU時(shí)間片輪轉(zhuǎn)方式,在宏觀上看起來(lái)同一時(shí)間段執(zhí)行多個(gè)任務(wù),但在事實(shí)上,對(duì)于單核CPU來(lái)說(shuō),任意具體時(shí)刻都只有一個(gè)任務(wù)在占用CPU資源。
隨著時(shí)間的推移,人們覺(jué)得這種方式還是有點(diǎn)效率低,不能夠滿足日常需求了。下面就是我們要講的線程的概念了
什么是線程
我們知道進(jìn)程在某一時(shí)刻只能處理一件事情,如果要處理其它的,只能等待前面的任務(wù)完成。于是呢,人們就提出了線程的概念。之前講進(jìn)程的概念的時(shí)候,其實(shí)還有一句話:
在當(dāng)代面向線程設(shè)計(jì)的計(jì)算機(jī)結(jié)構(gòu)中,進(jìn)程是線程的容器。程序是指令、數(shù)據(jù)及其組織形式的描述,進(jìn)程是程序的實(shí)體。
從中可知,線程是存于進(jìn)程之中,一個(gè)進(jìn)程可以有多個(gè)線程,一個(gè)線程可以處理一個(gè)子任務(wù),它是并發(fā)程序的基礎(chǔ)。有的人可能問(wèn)了,我多進(jìn)程處理不也可以嗎?使用多線程有什么優(yōu)勢(shì)?
首先我們需要知道的是處理一個(gè)程序不單單是執(zhí)行任務(wù),完了就結(jié)束了,往往我們的執(zhí)行的任務(wù)之間是互相依賴的,也就是說(shuō)任務(wù)之間需要交互,在這里叫進(jìn)程通信或者線程通信。下面我們就說(shuō)說(shuō)這兩者的比較
進(jìn)程通信 & 線程通信
首先我們要知道進(jìn)程和線程的本質(zhì)區(qū)別,線程是進(jìn)程的子集,一個(gè)進(jìn)程可以有多個(gè)線程。從運(yùn)行環(huán)境上可以得知,進(jìn)程是獨(dú)立的運(yùn)行環(huán)境, 線程是進(jìn)程下分配的一個(gè)子任務(wù),也就是說(shuō)進(jìn)程獨(dú)占系統(tǒng)資源和內(nèi)存空間。這樣一想,如果開(kāi)啟多個(gè)進(jìn)程是比較消耗系統(tǒng)資源的。進(jìn)程的創(chuàng)建和銷毀不僅需要保存寄存器和棧信息,還需要資源的分配回收以及調(diào)度,開(kāi)銷較大。線程只需要保存寄存器和棧信息,開(kāi)銷較小,所以這也是使用線程的優(yōu)勢(shì)。
進(jìn)程與進(jìn)程之間是互相隔離的,一個(gè)進(jìn)程出現(xiàn)問(wèn)題不會(huì)影響其它進(jìn)程的運(yùn)行,而線程崩潰是有可能影響整個(gè)程序的。另外一個(gè)重要區(qū)別是,進(jìn)程是操作系統(tǒng)進(jìn)行資源分配的基本單位,而線程是操作系統(tǒng)進(jìn)行調(diào)度的基本單位,即CPU分配時(shí)間的單位。
上下文切換過(guò)程
這個(gè)概念非常重要,大家一定要好好去理解~
寄存器
上面提到寄存器,那么它是啥呢?它和上下文切換脫不開(kāi)關(guān)系。上下文切換是指 CPU 從一個(gè)進(jìn)程(或線程)切換到另一個(gè)進(jìn)程(或線程)。上下文是指某一時(shí)間點(diǎn)CPU寄存器和程序計(jì)數(shù)器的內(nèi)容
寄存器是cpu內(nèi)部的少量的速度很快的閃存,通常存儲(chǔ)和訪問(wèn)計(jì)算過(guò)程的中間值提高計(jì)算機(jī)程序的運(yùn)行速度。
程序計(jì)數(shù)器
程序計(jì)數(shù)器是一個(gè)專用的寄存器,用于表明指令序列中CPU,正在執(zhí)行的位置,存的值為正在執(zhí)行的指令的位置或者下一個(gè)將要被執(zhí)行的指令的位置,具體實(shí)現(xiàn)依賴于特定的系統(tǒng)。
說(shuō)的有點(diǎn)抽象,給大家舉個(gè)例子。這里開(kāi)啟了兩個(gè)線程A,B。那么線程A怎么切到B的呢?
- 首先A線程掛起, 并將當(dāng)前在cpu中的狀態(tài)保存到內(nèi)存中。
- 在內(nèi)存中檢索下一個(gè)線程B的上下文并將其在CPU的寄存器中恢復(fù),執(zhí)行B線程。
- 當(dāng)B執(zhí)行完,根據(jù)程序計(jì)數(shù)器中指向的位置恢復(fù)線程A。
過(guò)程分析
CPU通過(guò)為每個(gè)線程分配CPU時(shí)間片來(lái)實(shí)現(xiàn)多線程機(jī)制,CPU通過(guò)時(shí)間片分配算法來(lái)循環(huán)執(zhí)行任務(wù),當(dāng)前任務(wù)執(zhí)行一個(gè)時(shí)間片后會(huì)切換到下一個(gè)任務(wù)。但是,在切換前會(huì)保存上一個(gè)任務(wù)的狀態(tài),以便下次切換回這個(gè)任務(wù)時(shí),可以再加載這個(gè)任務(wù)的狀態(tài),所以任務(wù)從保存到再加載的過(guò)程就是一次上下文切換。
??上下文切換通常是計(jì)算密集型的,意味著此操作會(huì)消耗大量的CPU時(shí)間, 如果你面試被問(wèn)到Redis為什么采用單線程I/O多路復(fù)用模型,這個(gè)地方是不是可以拿出來(lái)講一講呢?
結(jié)束語(yǔ)
本期到這里就結(jié)束了, 總結(jié)一下,本節(jié)主要講了什么是線程,什么是進(jìn)程,以及上下文切換的概念。這些概念性的東西,大家不要去背,要自己去理解,不懂的地方可以自己再去搜索,一定要理解,然后自己多總結(jié)總結(jié)~
標(biāo)題名稱:Java多線程專題之線程與進(jìn)程概述
網(wǎng)站URL:http://www.dlmjj.cn/article/djiigcs.html


咨詢
建站咨詢
