Java併發程式設計1.1—基礎概念
併發程式設計1.1—基礎概念
1.CPU核心數和執行緒數的關係和區別
簡單的說:
CPU核心數:執行緒數=1:1 ;使用了超執行緒技術後—> 1:2。
詳細解釋:
CPU核心數指物理上,也就是硬體上存在著幾個核心。比如,雙核就是包括2個相對獨立的CPU核心單元組,四核就包含4個相對獨立的CPU核心單元組,等等,依次類推。
執行緒數是一種邏輯的概念,簡單地說,就是模擬出的CPU核心數。比如,可以通過一個CPU核心數模擬出2執行緒的CPU,也就是說,這個單核心的CPU被模擬成了一個類似雙核心CPU的功能(超執行緒技術)。我們從工作管理員的效能標籤頁中看到的是兩個CPU。
超執行緒技術:超執行緒技術(HT)是INTER公司提出並研發的,於2002年釋出。超執行緒技術就是利用特殊的硬體指令,把一個物理核心模擬成兩個邏輯核心,讓單個處理器都能使用執行緒級平行計算,進而相容多執行緒作業系統和軟體,減少了CPU的閒置時間,提高了CPU的執行速度。(來自百度百科)
超執行緒技術是英特爾公司所研發的,所以,對於AMD的CPU來說,只有核心數的概念,沒有執行緒數的概念
2.CPU時間片輪轉排程
簡單的說:
時間片輪轉排程是一種最古老,最簡單,最公平且使用最廣的演算法。每個程序被分配一時間段,稱作它的時間片,即該程序允許執行的時間。
在巨集觀上:我們可以同時開啟多個應用程式,每個程式並行不悖,同時執行。但是在微觀上:由於只有一個CPU,一次只能處理程式要求的一部分,如何處理公平,一種方法就是引入時間片,每個程式輪流執行。
詳細解釋:
時間片輪轉法(Round-Robin,RR)主要用於分時系統中的程序排程。為了實現輪轉排程,系統把所有就緒程序按先入先出的原則排成一個佇列。新來的程序加到就緒佇列末尾。每當執行程序排程時,程序排程程式總是選出就緒佇列的隊首程序,讓它在CPU上執行一個時間片的時間。時間片是一個小的時間單位,通常為10~100ms數量級。當程序用完分給它的時間片後,系統的計時器發出時鐘中斷,排程程式便停止該程序的執行,把它放入就緒佇列的末尾;然後,把CPU分給就緒佇列的隊首程序,同樣也讓它執行一個時間片,如此往復。
當然在我們程式設計師看來,只需要理解程式是被作業系統片段執行的,每個片段就是一個時間片,就足夠了。既然是片段執行,程式設計師就必須理解,在自己的程式執行時不是獨一無二的,我們看似很順暢的工作,其實是由一個個的執行片段構成的,我們眼中相鄰的兩條語句甚至同一個語句中兩個不同的運算子之間,都有可能插入其他執行緒或程序的動作。
3.程序和執行緒
程序概念
程序是表示資源分配的基本單位,又是排程執行的基本單位。例如,使用者執行自己的程式,系統就建立一個程序,併為它分配資源,包括各種表格、記憶體空間、磁碟空間、I/O裝置等。然後,把該程序放人程序的就緒佇列。程序排程程式選中它,為它分配CPU以及其它有關資源,該程序才真正執行。所以,程序是系統中的併發執行的單位。
在Mac、Windows NT等採用微核心結構的作業系統中,程序的功能發生了變化:它只是資源分配的單位,而不再是排程執行的單位。在微核心系統中,真正排程執行的基本單位是執行緒。因此,實現併發功能的單位是執行緒。
執行緒概念
執行緒是程序中執行運算的最小單位,亦即執行處理機排程的基本單位。如果把程序理解為在邏輯上作業系統所完成的任務,那麼執行緒表示完成該任務的許多可能的子任務之一。例如,假設使用者啟動了一個視窗中的資料庫應用程式,作業系統就將對資料庫的呼叫表示為一個程序。假設使用者要從資料庫中產生一份工資單報表,並傳到一個檔案中,這是一個子任務;在產生工資單報表的過程中,使用者又可以輸人資料庫查詢請求,這又是一個子任務。這樣,作業系統則把每一個請求――工資單報表和新輸人的資料查詢表示為資料庫程序中的獨立的執行緒。執行緒可以在處理器上獨立排程執行,這樣,在多處理器環境下就允許幾個執行緒各自在單獨處理器上進行。作業系統提供執行緒就是為了方便而有效地實現這種併發性。
程序和執行緒的關係
(1)一個執行緒只能屬於一個程序,而一個程序可以有多個執行緒,但至少有一個執行緒。執行緒是作業系統可識別的最小執行和排程單位。
(2)資源分配給程序,同一程序的所有執行緒共享該程序的所有資源。 同一程序中的多個執行緒共享程式碼段(程式碼和常量),資料段(全域性變數和靜態變數),擴充套件段(堆儲存)。但是每個執行緒擁有自己的棧段,棧段又叫執行時段,用來存放所有區域性變數和臨時變數。
(3)處理機分給執行緒,即真正在處理機上執行的是執行緒。
(4)執行緒在執行過程中,需要協作同步。不同程序的執行緒間要利用訊息通訊的辦法實現同步。
4.並行和併發
簡單的說(課上老師好像都是這樣說的,但是這樣的說法是模稜兩可):
並行:同一時刻,可以同時處理事情的能力
併發:與單位時間相關,在單位時間內可以處理事情的能力
深入理解:
並行才是我們通常認為的那個同時做多件事情,而併發則是線上程這個模型下產生的概念。並發表示同時發生了多件事情,通過時間片切換,哪怕只有單一的核心,也可以實現“同時做多件事情”這個效果。根據底層是否有多處理器,併發與並行是可以等效的,這並不是兩個互斥的概念。舉個我們開發中會遇到的例子,我們說資源請求併發數達到了1萬。這裡的意思是有1萬個請求同時過來了。但是這裡很明顯不可能真正的同時去處理這1萬個請求的吧!如果這臺機器的處理器有4個核心,不考慮超執行緒,那麼我們認為同時會有4個執行緒在跑。也就是說,併發訪問數是1萬,而底層真實的並行處理的請求數是4。如果併發數小一些只有4的話,又或者你的機器牛逼有1萬個核心,那併發在這裡和並行一個效果。也就是說,併發可以是虛擬的同時執行,也可以是真的同時執行。而並行的意思是真的同時執行。結論是:並行是我們物理時空觀下的同時執行,而併發則是作業系統用執行緒這個模型抽象之後站線上程的視角上看到的“同時”執行。(摘自Bug輝 的部落格)
5.高併發程式設計的意義、好處和注意事項
總的來說:
好處:充分利用cpu的資源、加快使用者響應的時間,程式模組化,非同步化
問題:執行緒共享資源,存在衝突;容易導致死鎖;啟用太多的執行緒,就有搞垮機器的可能