java併發有諸多難點,實際上並非java語言本身的問題,本質上說一部分是因為併發操作本身的問題,另外一部分是因為計算機體系結構帶來的。為了更好地理解java併發過程中的問題,我們應該對CPU有一些基礎的認知。
CPU
在資訊時代,CPU是我們耳熟能詳的一個概念,大家都知道CPU就是計算機的大腦。計算機中一連串複雜的指令都是由它負責執行的,而這些指令通常就是我們稱之為程式的東西。那麼CPU到底是什麼呢?CPU即中央處理器,它是計算機中控制資料操控的電路。主要由三部分組成:算術/邏輯單元、控制單元、暫存器單元。
控制單元是整個CPU的指揮控制中心,它的主要職責就是協調機器活動,通過向其他兩個單元傳送控制指令來達到控制效果。算數/邏輯單元主要的職責是負責執行運算,包括算術和邏輯運算,它估計控制單元傳送過來的指令執行相應的運算操作。暫存器單元主要的作用是用來臨時儲存資料,它儲存著待處理的或者已經處理的資料,它的出現是為了減少CPU對記憶體的訪問次數,提升讀取資料的效能,從而提升CPU的整體工作效率。
cpu與記憶體的協作
CPU中的暫存器分為通用暫存器和專用暫存器,通用暫存器用於臨時存放CPU正在使用的資料,而專用暫存器用於CPU專有用途,比如指令暫存器和程式計數器。CPU與主存通過匯流排進行通訊,CPU通過控制單元能夠操作主存中的資料。
-執行兩個數值相加的大致過程為:從主存讀取第一個運算元放到暫存器A->從主存讀取第二個運算元放到暫存器B->兩個暫存器儲存的值作為輸入送入到加法電路->將加法結果儲存到暫存器C->控制單元將結果放入主存中。
程式等於資料
原始的計算機並不像現代計算機一樣將程式儲存起來,以前的人們只對資料進行儲存,而裝置執行的步驟作為計算機的一部分而被內建在控制單元中。這樣就很不靈活,最多通過重新佈線來提升靈活性。將程式和資料視作相同本質是很大的計算機思維的突破,因為人們一直認為它們是不同的事物,資料應該存放在主存中而程式應該屬於CPU的一部分。
將程式作為資料一樣儲存在主存中大有好處,控制單元能夠從主存讀取程式,然後對它們解碼並執行。當我們要修改執行程式時可以在計算機的主存中修改,而不必對CPU更改或者重新佈線。
指令系統
程式包含了大量的機器指令,CPU對這些指令進行解碼並執行。CPU分為兩類體系:精簡指令集計算機(RISC)和複雜指令級計算機(CISC)。RISC提供了最小的機器指令集,計算機效率高速度快且製造成本低。而CISC提供了強大豐富的指令集,能更方便實現複雜的軟體。
機器指令分為三類:資料傳輸類、算術/邏輯類、控制類。
資料傳輸類指令用於將資料從一個地方移動到另一個地方。比如將主存單元的內容載入到暫存器的LOAD指令,反之將暫存器的內容儲存到主存的STORE指令。此外,CPU與其他裝置(鍵盤、滑鼠、印表機、顯示器、磁碟等)進行通訊的指令被稱為I/O指令。
算術/邏輯類指令用於讓控制單元請求在算術/邏輯單元內執行運算。這些運算包括算術、與、或、異或和位移等。
控制類指令用於指導程式執行。比如轉移(JUMP)指令,它包括無條件轉移和條件轉移。
指令暫存器與程式計數器
CPU將主存的指令載入進來解碼並執行,其中涉及到兩個重要的暫存器:指令暫存器和程式計數器。指令暫存器用於儲存正在執行的指令,而程式計數器則保持下一個待執行的指令地址。
CPU向主存請求載入程式計數器指定的地址的指令,將其存放到指令暫存器中,載入後將程式計數器的值加2(加入指令長度為2個位元組)。
指令如何執行
比如我們要計算11+22,假設過程為:將主存地址為00的內容載入到暫存器A中->將主存地址為01的內容載入到暫存器B中->將暫存器A和暫存器B的資料相加並將結果儲存到暫存器C->將暫存器C的結果儲存到主存地址為02的位置->end。
這個過程CPU涉及到四個操作:載入(LOAD)、儲存(STORE)、加法(ADD)和停止(HALT)。可以對這些操作進行編碼,比如可以分別用1、2、3、0000表示。
控制器
CPU與其他裝置的通訊一般通過控制器來實現,控制器可能在主機板上,也可能以電路板形式插到主機板。控制器本身可以看成是小型計算機,也有自己簡單的CPU。以前每連線一種外設都需要購買相應的控制器,而現在隨著通用序列匯流排(USB)稱為通用的標準,很多外設都可以直接用USB控制器作為通訊介面。每個控制器都連線在匯流排上,通過匯流排進行通訊。
每個控制器可能被設計成對應一組地址引用,主存則會忽略這些地址引用。當CPU往這些地址傳送訊息時,其實是直接穿過主存而到控制器的,操作的是控制器而非主存。這種模式稱為儲存對映輸入/輸出。此外,這種模式的另一種實現可以在機器指令中提供特定的操作碼,專門用於與控制器通訊,這樣的操作碼稱為I/O指令。
直接儲存器存取
直接儲存器存取(DMA)是一種提升外設通訊效能的措施,CPU並非總是需要使用匯流排,在匯流排空閒的時間裡控制器能夠充分利用起來。因為控制器都與匯流排相連線,而控制器又有執行指令的能力,所以可以將CPU的一些工作分給控制器來完成。比如在磁碟中檢索資料時,CPU可以將告知控制器,然後由控制器找到資料並放到主存上,期間CPU可以去執行其他任務。這樣可以節省CPU資源。不過DMA會使得匯流排通訊過於複雜,而且會導致匯流排競爭問題。匯流排瓶頸源自馮.諾伊曼體系結構。