二、執行緒同步
我們都知道,程序是運轉中的程式,是為了在cpu上實現多道程式設計而發明的乙個概念。但是程序在乙個時間只能幹一件事情,如果想要同時幹兩件或者多件事情,例如同時看兩場電影,我們自然會想到傳說中的分身術,就像孫悟空那樣可以變出多個真身。雖然我們在現實中無法分身,但程序卻可以辦到,辦法就是執行緒。執行緒就是我們為了讓乙個程序能夠同時幹多件事情而發明的「分身術」。
。例如,當我們使用microsoft word時,實際上是開啟了多個執行緒。這些執行緒乙個負責顯示,乙個負責接收輸入,乙個定時進行存檔…這些執行緒一起運轉,讓我們感覺到輸入和顯示同時發生,而不用鍵入一些字元等待一會兒才顯示到螢幕上。在不經意間,word還能定期自動儲存。
現代作業系統結合了使用者態和核心態的執行緒模型,其中使用者態的執行系統負責程序內部在非阻塞時的切換,而核心態的作業系統則負責阻塞執行緒的切換,即同時實現核心態和使用者態執行緒管理。其中,核心態執行緒數量極少,而使用者態執行緒數量較多。每個核心態執行緒可以服務乙個或多個使用者態執行緒。換句話說,使用者態執行緒會被多路復用到核心態執行緒上。
推出執行緒模型的目的就是實現程序級併發,因為在乙個程序中通常會出現多個執行緒。多個執行緒共享乙個舞台,時而互動,時而獨舞。但是,共享乙個舞台會帶來不必要的麻煩,這些麻煩歸結到下面兩個根本問題:
出現上述問題原因在於兩點:一是執行緒之間共享的全域性變數;二是執行緒之間的相對執行順序是不確定的。針對第一點,如果所有資源都不共享,那就違背了程序和執行緒設計的初衷:資源共享、提高資源利用率。針對第二點,需要讓執行緒之間的相對執行順序在需要的時候可以確定。
【鎖】:
鎖有兩個基本操作:上鎖和解鎖。很容易理解,上鎖就是將鎖鎖上,其他人進不來;解鎖就是你做的事情做完了,將鎖開啟,別的人可以進去了。解鎖只有乙個步驟那就是開啟鎖,而上鎖有兩個步驟:一是等待鎖達到開啟狀態,二是獲得鎖並鎖上。顯然,上鎖的兩個操作應該是原子操作,不能分開。
【訊號量】:
訊號量(semaphore)是乙個計數器,其取值為當前累積的訊號數量。它支援兩個操作:加法操作up和減法操作down。執行down減法操作時,請求該訊號量的乙個執行緒會被掛起;而執行up加法操作時,會叫醒乙個在該訊號量上面等待的執行緒。down和up操作在歷史上被稱為p和v操作,是作業系統中最重要的同步原語的兩個基本操作。
有些房間,可以同時容納n個人,比如廚房。也就是說,如果人數大於n,多出來的人只能在外面等著。這好比某些記憶體區域,只能供給固定數目的執行緒使用。這時的解決方法,就是在門口掛n把鑰匙。進去的人就取一把鑰匙,出來時再把鑰匙掛回原處。後到的人發現鑰匙架空了,就知道必須在門口排隊等著了。這種做法就叫做"訊號量",用來保證多個執行緒不會互相衝突。
執行緒同步基礎
多個執行緒同時訪問共享資料時可能會衝突。比如兩個執行緒都要把某個全域性變數增加1,這個操作在某平台需要三條指令完成 1.從記憶體讀變數值到暫存器 2.暫存器的值加1 3.將暫存器的值寫回記憶體 假設兩個執行緒在多處理器平台上同時執行這三條指令,則可能導致上圖所示的結果,最後變數只加了一次而非兩次 i...
執行緒安全與執行緒同步
執行緒安全 可重入函式 執行緒之間共享全域性資料段 靜態資料,引起非執行緒安全。執行緒安全可以通過執行緒同步對臨界資源訪問進行控制來實現。有些系統呼叫或者庫函式的實現時發生不安全現象,在多執行緒環境下就需要使用這些函式的安全版本,即可重入函式。例如 字串分割函式 普通版本 char strtok c...
執行緒安全與同步執行緒
資料有負數,相同的情況 比如在進行搶票的時候。可能會出現在第資料不準確的現象 public class unsafe implements runnable public static void test catch interruptedexception e system.out.println...