真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

「阿里面試系列」搞懂并發(fā)編程,輕松應(yīng)對(duì)80%的面試場(chǎng)景

關(guān)注我的架構(gòu)技術(shù)公眾號(hào):“架構(gòu)師修煉寶典”

目前創(chuàng)新互聯(lián)已為上1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)站空間、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計(jì)、興和網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

一周出產(chǎn)1-2篇技術(shù)文章,希望在你的架構(gòu)技術(shù)路上有我的點(diǎn)滴陪伴!

作為一個(gè)合格的Java程序員,必須要對(duì)并發(fā)編程有一個(gè)深層次的了解,在很多互聯(lián)網(wǎng)企業(yè)都會(huì)重點(diǎn)考察這一塊??赡芎芏喙ぷ?年以上的Java程序員對(duì)于這一領(lǐng)域幾乎沒(méi)有太多研究。所以在接下來(lái)內(nèi)容中,我會(huì)將并發(fā)編程整個(gè)領(lǐng)域由淺到深做非常全面的分析。

內(nèi)容導(dǎo)航

  • 從操作系統(tǒng)的發(fā)展了解進(jìn)程、線程模型

  • 線程的優(yōu)勢(shì)

  • 線程的生命周期

  • 線程的應(yīng)用場(chǎng)景

了解進(jìn)程、線程模型

每次學(xué)習(xí)一個(gè)新技術(shù),我會(huì)先去了解這個(gè)技術(shù)的背景,這個(gè)過(guò)程看似浪費(fèi)時(shí)間,其實(shí)在后續(xù)的學(xué)習(xí)過(guò)程中,能夠促進(jìn)理解很多問(wèn)題。所以對(duì)于線程這個(gè)概念,我會(huì)先從操作系統(tǒng)講起。因?yàn)椴僮飨到y(tǒng)的發(fā)展帶來(lái)了軟件層面的變革。 從多線程的發(fā)展來(lái)看,可以操作系統(tǒng)的發(fā)展分為三個(gè)歷史階段:

  • 真空管和穿孔卡片

  • 晶體管和批處理系統(tǒng)

  • 集成電路和多道程序設(shè)計(jì)

最早的計(jì)算機(jī)只能解決簡(jiǎn)單的數(shù)學(xué)運(yùn)算問(wèn)題,比如正弦、余弦等。運(yùn)行方式:程序員首先把程序?qū)懙郊埳希缓蟠┛壮煽ㄆ?,再把卡片盒帶入到?zhuān)門(mén)的輸入室。輸入室會(huì)有專(zhuān)門(mén)的操作員將卡片的程序輸入到計(jì)算機(jī)上。計(jì)算機(jī)運(yùn)行完當(dāng)前的任務(wù)以后,把計(jì)算結(jié)果從打印機(jī)上進(jìn)行輸出,操作員再把打印出來(lái)的結(jié)果送入到輸出室,程序員就可以從輸出室取到結(jié)果。然后,操作員再繼續(xù)從已經(jīng)送入到輸入室的卡片盒中讀入另一個(gè)任務(wù)重復(fù)上述的步驟。

操作員在機(jī)房里面來(lái)回調(diào)度資源,造成計(jì)算機(jī)存在大量的空閑狀態(tài) 。而當(dāng)時(shí)的計(jì)算機(jī)是非常昂貴的,人們?yōu)榱藴p少這種資源的浪費(fèi)。就采用了 批處理系統(tǒng)來(lái)解決

批處理操作系統(tǒng) 的運(yùn)行方式:在輸入室收集全部的作業(yè),然后用一臺(tái)比較便宜的計(jì)算機(jī)把它們讀取到磁帶上。然后把磁帶輸入到計(jì)算機(jī),計(jì)算機(jī)通過(guò)讀取磁帶的指令來(lái)進(jìn)行運(yùn)算,最后把結(jié)果輸出磁帶上。批處理操作系統(tǒng)的好處在于,計(jì)算機(jī)會(huì)一直處于運(yùn)算狀態(tài),合理的利用了計(jì)算機(jī)資源。(運(yùn)行流程如下圖所示)

「阿里面試系列」搞懂并發(fā)編程,輕松應(yīng)對(duì)80%的面試場(chǎng)景

(注:此圖來(lái)源于現(xiàn)代操作系統(tǒng))

批處理操作系統(tǒng)雖然能夠解決計(jì)算機(jī)的空閑問(wèn)題,但是當(dāng)某一個(gè)作業(yè)因?yàn)榈却疟P(pán)或者其他I/O操作而暫停,那CPU就只能阻塞直到該I/O完成,對(duì)于CPU操作密集型的程序,I/O操作相對(duì)較少,因此浪費(fèi)的時(shí)間也很少。但是對(duì)于I/O操作較多的場(chǎng)景來(lái)說(shuō),CPU的資源是屬于嚴(yán)重浪費(fèi)的。

多道程序設(shè)計(jì) 的出現(xiàn)解決了這個(gè)問(wèn)題,就是把內(nèi)存分為幾個(gè)部分,每一個(gè)部分放不同的程序。當(dāng)一個(gè)程序需要等待I/O操作完成時(shí)。那么CPU可以切換執(zhí)行內(nèi)存中的另外一個(gè)程序。如果內(nèi)存中可以同時(shí)存放足夠多的程序,那CPU的利用率可以接近100%。 在這個(gè)時(shí)候,引入了第一個(gè)概念-  進(jìn)程 , 進(jìn)程的本質(zhì)是一個(gè)正在執(zhí)行的程序,程序運(yùn)行時(shí)系統(tǒng)會(huì)創(chuàng)建一個(gè)進(jìn)程,并且給每個(gè)進(jìn)程分配獨(dú)立的內(nèi)存地址空間保證每個(gè)進(jìn)程地址不會(huì)相互干擾。同時(shí),在CPU對(duì)進(jìn)程做時(shí)間片的切換時(shí),保證進(jìn)程切換過(guò)程中仍然要從進(jìn)程切換之前運(yùn)行的位置出開(kāi)始執(zhí)行。所以進(jìn)程通常還會(huì)包括程序計(jì)數(shù)器、堆棧指針。

有了進(jìn)程以后,可以讓操作系統(tǒng)從宏觀層面實(shí)現(xiàn)多應(yīng)用并發(fā)。而并發(fā)的實(shí)現(xiàn)是通過(guò)CPU時(shí)間片不端切換執(zhí)行的。對(duì)于單核CPU來(lái)說(shuō),在任意一個(gè)時(shí)刻只會(huì)有一個(gè)進(jìn)程在被CPU調(diào)度

有了進(jìn)程以后,為什么還會(huì)出現(xiàn)線程呢?

在一個(gè)應(yīng)用進(jìn)程中,會(huì)存在多個(gè)同時(shí)執(zhí)行的任務(wù),如果其中一個(gè)任務(wù)被阻塞,將會(huì)引起不依賴(lài)該任務(wù)的任務(wù)也被阻塞。舉個(gè)具體的例子來(lái)說(shuō),我們平常用word文檔編輯內(nèi)容的時(shí)候,都會(huì)有一個(gè)自動(dòng)保存的功能,這個(gè)功能的作用是,當(dāng)計(jì)算機(jī)出現(xiàn)故障的情況下如果用戶未保存文檔,則能夠恢復(fù)到上一次自動(dòng)保存的點(diǎn)。假設(shè)word的自動(dòng)保存因?yàn)榇疟P(pán)問(wèn)題導(dǎo)致寫(xiě)入較慢,勢(shì)必會(huì)影響到用戶的文檔編輯功能,直到磁盤(pán)寫(xiě)入完成用戶才可編輯,這種體驗(yàn)是很差的。如果我們把一個(gè)進(jìn)程中的多個(gè)任務(wù)通過(guò)線程的方式進(jìn)行隔離,那么按照前面提到的進(jìn)程演進(jìn)的理論來(lái)說(shuō),在單核心CPU架構(gòu)中可以通過(guò)CPU的時(shí)間片切換實(shí)現(xiàn)線程的調(diào)度充分利用CPU資源以達(dá)到最大的性能。加Q群:725219329可獲取一份Java架構(gòu)進(jìn)階技術(shù)精品視頻。(高并發(fā)+Spring源碼+JVM原理解析+分布式架構(gòu)+微服務(wù)架構(gòu)+多線程并發(fā)原理+BATJ面試寶典)

我們用了比較長(zhǎng)的篇幅介紹了進(jìn)程、線程發(fā)展的歷史??偟膩?lái)說(shuō)是人們對(duì)于計(jì)算機(jī)的要求越來(lái)越高;對(duì)于計(jì)算機(jī)本身的資源的利用率也在不斷提高。

線程的優(yōu)勢(shì)

前面分析了線程的發(fā)展歷史,這里簡(jiǎn)單總結(jié)一下線程有的優(yōu)勢(shì)如下

  • 線程可以認(rèn)為是輕量級(jí)的進(jìn)程,所以線程的創(chuàng)建、銷(xiāo)毀要比進(jìn)程更快

  • 從性能上考慮,如果進(jìn)程中存在大量的I/O處理,通過(guò)多線程能夠加快應(yīng)用程序的執(zhí)行速度(通過(guò)CPU時(shí)間片的快速切換)。

  • 由于線程是CPU的最小調(diào)度單元,所以在多CPU架構(gòu)中能夠?qū)崿F(xiàn)真正的 并行 執(zhí)行。每一個(gè)CPU可以調(diào)度一個(gè)線程

這里有兩個(gè)概念很多人沒(méi)有搞明白,就是并行和并發(fā)
并行 :同時(shí)執(zhí)行多個(gè)任務(wù),在多核心CPU架構(gòu)中,一個(gè)CPU核心運(yùn)行一個(gè)線程,那么4核心CPU,可以同時(shí)執(zhí)行4個(gè)線程
并發(fā) :同處理多個(gè)任務(wù)的能力,通常我們會(huì)通過(guò)TPS或者QPS來(lái)表示某某系統(tǒng)支持的并發(fā)數(shù)是多少。

總的來(lái)說(shuō),并行是并發(fā)的子集。也就是說(shuō)我們可以寫(xiě)一個(gè)擁有多線程并行的程序,如果在沒(méi)有多核心CPU來(lái)執(zhí)行這些線程,那就不能以并行的方式來(lái)運(yùn)行程序中的多個(gè)線程。所以并發(fā)程序可以是并行的,也可以不是。 Erlang之父Joe Armstrong通過(guò)一張圖型的方式來(lái)解釋并發(fā)和并行的區(qū)別,圖片如下

「阿里面試系列」搞懂并發(fā)編程,輕松應(yīng)對(duì)80%的面試場(chǎng)景

線程的生命周期

線程是存在生命周期的,從線程的創(chuàng)建到銷(xiāo)毀,可能會(huì)經(jīng)歷6種不同的狀態(tài),但是在一個(gè)時(shí)刻線程只能處于其中一種狀態(tài)

  • NEW:初始狀態(tài),線程被創(chuàng)建時(shí)候的狀態(tài),還沒(méi)有調(diào)用start方法

  • RUNNABLE:運(yùn)行狀態(tài),運(yùn)行狀態(tài)包含就緒和運(yùn)行兩種狀態(tài),因?yàn)榫€程啟動(dòng)以后,并不是立即執(zhí)行,而是需要通過(guò)調(diào)度去分配CPU時(shí)間片

  • BLOCKED:阻塞狀態(tài),當(dāng)線程去訪問(wèn)一個(gè)加鎖的方法時(shí),如果已經(jīng)有其他線程獲得鎖,那么當(dāng)前線程會(huì)處于阻塞狀態(tài)

  • WAITING:等待狀態(tài),設(shè)置線程進(jìn)入等待狀態(tài)等待其他線程做一些特定的動(dòng)作進(jìn)行觸發(fā)

  • TIME_WAITING:超時(shí)等待狀態(tài),和WAITING狀態(tài)的區(qū)別在于超時(shí)以后自動(dòng)返回

  • TERMINATED:終止?fàn)顟B(tài),線程執(zhí)行完畢

下圖整理了線程的狀態(tài)變更過(guò)程及變更的操作,每一個(gè)具體的操作原理,我會(huì)在后續(xù)的文章中進(jìn)行詳細(xì)分析。

這里有一個(gè)問(wèn)題大家可能搞不明白,BLOCKED和WAITING這兩個(gè)阻塞有什么區(qū)別?

  • BLOCKED狀態(tài)是指當(dāng)前線程在等待一個(gè)獲取鎖的操作時(shí)的狀態(tài)。

  • WAITING是通過(guò)Object.wait或者Thread.join、LockSupport.park等操作實(shí)現(xiàn)的

  • BLOCKED是被動(dòng)的標(biāo)記,而WAITING是主動(dòng)操作

  • 如果說(shuō)得再深入一點(diǎn),處于WAITING狀態(tài)的線程,被喚醒以后,需要進(jìn)入同步隊(duì)列去競(jìng)爭(zhēng)鎖操作,而在同步隊(duì)列中,如果已經(jīng)有其他線程持有鎖,則線程會(huì)處于BLOCKED狀態(tài)。所以可以說(shuō)BLOCKED狀態(tài)是處于WAITING狀態(tài)的線程重新喚醒的必經(jīng)的狀態(tài)

線程的應(yīng)用場(chǎng)景

線程的出現(xiàn),在多核心CPU架構(gòu)下實(shí)現(xiàn)了真正意義上的并行執(zhí)行。也就是說(shuō),一個(gè)進(jìn)程內(nèi)多個(gè)任務(wù)可以通過(guò)多線程并行執(zhí)行來(lái)提高程序運(yùn)行的性能。那線程的使用場(chǎng)景有哪些呢?

  • 執(zhí)行后臺(tái)任務(wù),在很多場(chǎng)景中,可能會(huì)有一些定時(shí)的批量任務(wù),比如定時(shí)發(fā)送短信、定時(shí)生成批量文件。在這些場(chǎng)景中可以通過(guò)多線程的來(lái)執(zhí)行

  • 異步處理,比如在用戶注冊(cè)成功以后給用戶發(fā)送優(yōu)惠券或者短信,可以通過(guò)異步的方式來(lái)執(zhí)行,一方面提升主程序的執(zhí)行性能;另一方面可以解耦核心功能,防止非核心功能對(duì)核心功能造成影響

  • 分布式處理,比如fork/join,將一個(gè)任務(wù)拆分成多個(gè)子任務(wù)分別執(zhí)行

  • BIO模型中的線程任務(wù)分發(fā),也是一種比較常見(jiàn)的使用場(chǎng)景,一個(gè)請(qǐng)求對(duì)應(yīng)一個(gè)線程。加Q群:725219329可獲取一份Java架構(gòu)進(jìn)階技術(shù)精品視頻。(高并發(fā)+Spring源碼+JVM原理解析+分布式架構(gòu)+微服務(wù)架構(gòu)+多線程并發(fā)原理+BATJ面試寶典)

合理的利用多線程,可以提升程序的吞吐量。同時(shí),還可以通過(guò)增加CPU的核心數(shù)來(lái)提升程序的性能,這就體現(xiàn)了伸縮性的特點(diǎn)

關(guān)注我的架構(gòu)技術(shù)公眾號(hào):“架構(gòu)師修煉寶典”

一周出產(chǎn)1-2篇技術(shù)文章,希望在你的架構(gòu)技術(shù)路上有我的點(diǎn)滴陪伴!


網(wǎng)頁(yè)標(biāo)題:「阿里面試系列」搞懂并發(fā)編程,輕松應(yīng)對(duì)80%的面試場(chǎng)景
標(biāo)題URL:http://weahome.cn/article/jjjshc.html

其他資訊

在線咨詢(xún)

微信咨詢(xún)

電話咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部