版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
程序員大家都在用的并發(fā)到底是個什么?資料僅供參考寫在前面并發(fā)與操作系統(tǒng)的生命歷程息息相關(guān)。進程的出現(xiàn),使得程序狀態(tài)的保存變?yōu)楝F(xiàn)實,為進程間的切換提供了可能,實現(xiàn)了操作系統(tǒng)的并發(fā),大大提高資源利用率。雖然進程的出現(xiàn)解決了操作系統(tǒng)的并發(fā)問題,但人們對實時性又有了更高的要求。由于一個進程由若干個子任務(wù)組成,因此人們就創(chuàng)造了線程,讓每個線程負責一個獨立的子任務(wù),提高程序的響應(yīng)靈敏度。一個進程雖然包括多個線程,可是這些線程是共同享有進程占有的資源和地址空間的。因此,雖然多線程提高了資源利用率,保證了實時性,但同時也帶來了包括安全性、活躍性和性能等問題??偟膩碚f,進程讓操作系統(tǒng)的并發(fā)性成為可能,而線程讓進程的內(nèi)部并發(fā)成為可能。進程和線程的由來操作系統(tǒng)中為什么會出現(xiàn)進程?說起進程的由來,我們需要從操作系統(tǒng)的發(fā)展歷史談起。可能在今天,我們無法想象在很多年以前計算機是什么樣子。我們現(xiàn)在能夠用計算機來做很多事情:辦公、娛樂、上網(wǎng),可是在計算機剛出現(xiàn)的時候,是為了解決數(shù)學計算的問題,因為很多大量的計算經(jīng)過人力去完成是很耗時間和人力成本的。在最初的時候,計算機只能接受一些特定的指令,用戶輸入一個指令,計算機就做一個操作。當用戶在思考或者輸入數(shù)據(jù)時,計算機就在等待。顯然,這樣效率會很低下,因為很多時候,計算機處于等待用戶輸入的狀態(tài)。那么,能不能把一系列需要操作的指令預(yù)先寫下來,形成一個清單,然后一次性交給計算機,計算機不斷地去讀取指令來進行相應(yīng)的操作?就這樣,
批處理操作系統(tǒng)誕生了。用戶能夠?qū)⑿枰獔?zhí)行的多個程序?qū)懺诖艓?,然后交由計算機去讀取并逐個地執(zhí)行這些程序,并將輸出結(jié)果寫到另一個磁帶上。雖然批處理操作系統(tǒng)的誕生極大地提高了任務(wù)處理的便捷性,可是依然存在一個很大的問題:假如有兩個任務(wù)A和B,任務(wù)A在執(zhí)行到一半的過程中,需要讀取大量的數(shù)據(jù)輸入(I/O操作),而此時CPU只能靜靜地等待任務(wù)A讀取完數(shù)據(jù)才能繼續(xù)執(zhí)行,這樣就白白浪費了CPU資源。人們于是想,能否在任務(wù)A讀取數(shù)據(jù)的過程中,讓任務(wù)B去執(zhí)行,當任務(wù)A讀取完數(shù)據(jù)之后,讓任務(wù)B暫停,然后讓任務(wù)A繼續(xù)執(zhí)行?可是這樣就有一個問題,原來每次都是一個程序在計算機里面運行,也就說內(nèi)存中始終只有一個程序的運行數(shù)據(jù)。而如果想要任務(wù)A執(zhí)行I/O操作的時候,讓任務(wù)B去執(zhí)行,必然內(nèi)存中要裝入多個程序,那么如何處理呢?多個程序使用的數(shù)據(jù)如何進行辨別呢?而且,當一個程序運行暫停后,后面如何恢復(fù)到它之前執(zhí)行的狀態(tài)呢?這個時候,人們就創(chuàng)造了進程,用進程來對應(yīng)一個程序,每個進程對應(yīng)一定的內(nèi)存地址空間,而且只能使用它自己的內(nèi)存空間,各個進程間互不干擾。而且,進程保存了程序每個時刻的運行狀態(tài),這樣就為進程切換提供了可能。當進程暫停時,它會保存當前進程的狀態(tài)(比如進程標識、進程的使用的資源等),在下一次重新切換回來時,便根據(jù)之前保存的狀態(tài)進行恢復(fù),然后繼續(xù)執(zhí)行。這就是并發(fā),能夠讓操作系統(tǒng)從宏觀上看起來同一個時間段有多個任務(wù)在執(zhí)行。換句話說,進程讓操作系統(tǒng)的并發(fā)成為了可能。注意,雖然并發(fā)從宏觀上看有多個任務(wù)在執(zhí)行,可是事實上,任一個具體的時刻,只有一個任務(wù)在占用CPU資源(當然是對于單核CPU來說的)。為什么會出現(xiàn)線程?在出現(xiàn)了進程以后,操作系統(tǒng)的性能得到了大大的提升。雖然進程的出現(xiàn)解決了操作系統(tǒng)的并發(fā)問題,可是人們依然不滿足,人們逐漸對實時性有了要求。因為一個進程在一個時間段內(nèi)只能做一件事情,如果一個進程有多個子任務(wù),只能逐個地去執(zhí)行這些子任務(wù)。比如,對于一個監(jiān)控系統(tǒng)來說,它不但要把圖像數(shù)據(jù)顯示在畫面上,還要與服務(wù)端進行通信獲取圖像數(shù)據(jù),還要處理人們的交互操作。如果某一個時刻該系統(tǒng)正在與服務(wù)器通信獲取圖像數(shù)據(jù),而用戶又在監(jiān)控系統(tǒng)上點擊了某個按鈕,那么該系統(tǒng)就要等待獲取完圖像數(shù)據(jù)之后才能處理用戶的操作,如果獲取圖像數(shù)據(jù)需要耗費10s,那么用戶就只有一直等待。顯然,對于這樣的系統(tǒng),人們是無法滿足的。那么,可不能夠?qū)⑦@些子任務(wù)分開執(zhí)行呢?即,在系統(tǒng)獲取圖像數(shù)據(jù)的同時,如果用戶點擊了某個按鈕,則會暫停獲取圖像數(shù)據(jù),而先去響應(yīng)用戶的操作(因為用戶的操作往往執(zhí)行時間很短),在處理完用戶操作之后,再繼續(xù)獲取圖像數(shù)據(jù)。人們就創(chuàng)造了線程,讓一個線程去執(zhí)行一個子任務(wù),這樣一個進程就包括了多個線程,每個線程負責一個獨立的子任務(wù)。這樣,在用戶點擊按鈕的時候,就能夠暫停獲取圖像數(shù)據(jù)的線程,讓UI線程響應(yīng)用戶的操作,響應(yīng)完之后再切換回來,讓獲取圖像的線程得到CPU資源。從而,讓用戶感覺系統(tǒng)是同時在做多件事情的,滿足了用戶對實時性的要求。換句話說,進程讓操作系統(tǒng)的并發(fā)性成為可能,而線程讓進程的內(nèi)部并發(fā)成為可能。可是要注意,一個進程雖然包括多個線程,可是這些線程是共同享有進程占有的資源和地址空間的。進程是操作系統(tǒng)進行資源分配的基本單位,而線程是操作系統(tǒng)進行調(diào)度的基本單位。多線程并發(fā)由于多個線程是共同占有所屬進程的資源和地址空間的,那么就會存在一個問題:如果多個線程要同時訪問某個資源,怎么處理?這個問題就是并發(fā)安全性問題。另外,可能有朋友會問,現(xiàn)在很多時候都采用多線程編程,那么是不是多線程的性能一定就由于單線程呢?答案是不一定,要看具體的任務(wù)以及計算機的配置。比如說:對于單核CPU,如果是CPU密集型任務(wù),如解壓文件,多線程的性能反而不如單線程性能,因為解壓文件需要一直占用CPU資源,如果采用多線程,線程切換導致的開銷反而會讓性能下降??墒菍τ诒热缃换ヮ愋偷娜蝿?wù),肯定是需要使用多線程的。而對于多核CPU,對于解壓文件來說,多線程肯定優(yōu)于單線程,因為多個線程能夠更加充分利用每個核的資源。雖然多線程能夠提升程序性能,可是相對于單線程來說,它的編程要復(fù)雜地多,要考慮線程安全問題。因此,在實際編程過程中,要根據(jù)實際情況具體選擇。并發(fā)簡史總結(jié)早期的計算機不包含操作系統(tǒng),它們從頭到尾只執(zhí)行一個程序,而且這個程序能夠訪問計算機中的所有資源。這對于昂貴且稀有的計算機資源來說是一種浪費;操作系統(tǒng)的出現(xiàn)使得計算機能同時運行多個程序,不同的程序都在單獨的進程中運行,而且操作系統(tǒng)為各個獨立執(zhí)行的進程分配資源(eg:經(jīng)過粗粒度時間分片使程序共享資源,如CPU等)。這無疑提高了計算機資源的利用率;在早期的分時系統(tǒng)中,每個進程的執(zhí)行都是串行的。串行編程模型的優(yōu)勢在于其簡單性和直觀性,因為它每次只做一件事情,做完之后再做另一件。這種串行編程模型依然存在著計算機資源利用率不高的問題;促使進程出現(xiàn)的因素同樣也促使著線程的出現(xiàn)。線程允許在同一個進程中同時存在多個程序控制流。線程會共享進程范圍內(nèi)的資源,但每個線程都有各自的程序計數(shù)器、棧以及局部變量等等;線程也被成為輕量級進程。在大多數(shù)現(xiàn)代操作系統(tǒng)中,都是以線程為基本的調(diào)度單位,而不是進程。如果沒有明確的協(xié)同機制,那么線程將彼此獨立執(zhí)行。由于同一個進程的所有線程都將共享進程的內(nèi)存地址空間,因此這些線程都能訪問相同的變量,這就需要實現(xiàn)一種比進程間共享數(shù)據(jù)粒度更細的數(shù)據(jù)共享機制。如果沒有明確的同步機制來協(xié)同對共享數(shù)據(jù)的訪問,將造成不可預(yù)測的結(jié)果。線程的優(yōu)勢解耦、簡化程序開發(fā)在程序中,如果我們?yōu)槊糠N類型的任務(wù)都分配一個專門的線程,那么能夠形成一種串行執(zhí)行的假象,并將程序的執(zhí)行邏輯與調(diào)度機制的細節(jié),交替執(zhí)行的操作,異步I/O以及資源等待等問題分離開來。經(jīng)過使用線程,能夠?qū)?fù)雜而且異步的工作流進一步分解為一組簡單而且同步的工作流,每個工作流在一個單獨的線程中運行,并在特定的同步位置進行交互。Servlet框架就是一個很好的例子。框架負責解決一些細節(jié)問題,包括請求管理、線程創(chuàng)立、負載平衡等,并在正確的時刻將請求分發(fā)給正確的應(yīng)用程序組件(對應(yīng)的一個具體Servlet)。編寫Servlet的開發(fā)人員不需要了解有多少請求在同一時刻被處理,也不需要了解套接字的輸入(出)流是否被阻塞。當調(diào)用Servlet的service方法來響應(yīng)Web請求時,能夠以同步方式來處理這個請求,就仿佛它是一個單線程的程序。這種方式簡化了組件的開發(fā),大大降低框架學習門檻。多線程還有助于用戶界面的靈敏響應(yīng)。例如,在Android開發(fā)中,我們常常將網(wǎng)路請求或I/O等耗時操作單獨放到一個線程中,以提高響應(yīng)的靈敏度。提高資源利用率多處理器系統(tǒng)的出現(xiàn),使得同一個程序的多個線程能夠被同時調(diào)度到多個CPU上運行。因此,多線程程序能夠經(jīng)過提高處理器資源的利用率來提升系統(tǒng)的吞吐率。其實,多線程程序也有助于在單處理器系統(tǒng)上獲得更高的吞吐率(如果程序的一個線程在等待I/O操作的完成,另一個線程能夠繼續(xù)運行,使程序能夠在I/O阻塞期間繼續(xù)運行)。線程帶來的風險安全性問題在線程安全性的定義中,最核心的概念就是正確性。當多個線程訪問某個類時,不論運行時環(huán)境采用何種調(diào)度方式或者這些線程將如何交替執(zhí)行,而且在主調(diào)代碼中不需要任何額外的同步或協(xié)同,這個類都能表現(xiàn)出正確的行為,那么這個類就是線程安全的。線程不安全類示例:@NotThreadSafe
publicclassUnsafeSequence{
privateintvalue;
/**Returnsauniquevalue.*/
publicintgetNext(){
returnvalue++;
}
}雖然
遞增運算“value++”看上去是單個操作,但實際上它包含三個獨立的操作:讀取value,將value加1,并將計算結(jié)果寫入value。由于運行時各個線程執(zhí)行順序的不確定性,可能這段代碼在不同線程的調(diào)用中返回相同的數(shù)值活躍性問題活躍性問題關(guān)注的是:某件正確的事情最終會發(fā)生。導致活躍性的問題包括死鎖、饑餓等。性能問題性能問題關(guān)注的是:正確的事情能夠盡快發(fā)生。性能問題包括多個方面,例如響應(yīng)不靈敏,吞吐率過低,資源消耗過高等。在多線程程序中,當線程調(diào)度器臨時掛起活躍線程并轉(zhuǎn)而運行另一個線程時,就會頻繁出現(xiàn)上下文切換操作(ContextSwitch),這種操作會導致CPU時間更多的花在線程調(diào)度上而非線程的運行上。線程無處不在在Java中,一個應(yīng)用程序?qū)?yīng)著一個JVM實例(JVM進程)。Java采用的是單線程編程模型,即在我們自己的程序中如果沒有主動創(chuàng)立線程的話,只會創(chuàng)立一個線程,一般稱為主線程。可是要注意,雖然只有一個線程來執(zhí)行任務(wù),不代表JVM中只有一個線程,JVM實例在創(chuàng)立的時候,同時會創(chuàng)立很多其它的線程(比如垃圾收集器線程)。由于Java采用的是單線程編程模型,因此在進行UI編程時要注意將耗時的操作放在子線程中進行,以避免阻塞主線程(在UI編程時,主線程即UI線程,用來處理用戶的交互事件)。publicclassTest{
publicstaticvoidmain(String[]args)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2023年藍寶石晶體材料項目融資計劃書
- 2023年電池充電器項目籌資方案
- 烹飪原料知識測試題及參考答案
- 養(yǎng)老院老人生活照顧人員行為規(guī)范制度
- 養(yǎng)老院老人健康監(jiān)測制度
- 新疆維吾爾自治區(qū)青少年運動員注冊協(xié)議書(2篇)
- 承包采摘黃秋葵合同協(xié)議書范本(2篇)
- 2024全新水利工程監(jiān)理居間合同模板下載3篇
- 《建筑設(shè)計市場調(diào)研》課件
- 《向解放軍學執(zhí)行》課件
- 汽車技工的汽車維修技能培訓
- 綜合英語智慧樹知到期末考試答案章節(jié)答案2024年喀什大學
- 口腔科醫(yī)療安全隱患
- (正式版)SHT 3078-2024 立式圓筒形料倉工程設(shè)計規(guī)范
- (正式版)JCT 2769-2024 混凝土用鐵尾礦碎石
- 外側(cè)Hoffa骨折手術(shù)入路
- 感染性休克的急診處置規(guī)范
- 2023年全國統(tǒng)一高考化學試卷(遼寧卷)含答案與解析
- 臨床醫(yī)學檢驗:抗微生物藥物和敏感性試藥試題及答案真題
- 2024年中國鐵道科學研究院集團有限公司招聘筆試參考題庫附帶答案詳解
- 組合機床動力滑臺液壓系統(tǒng)設(shè)計
評論
0/150
提交評論