同步機制應該遵循的基本准則
· 空閑讓進:當無進程處於臨界區時,表明臨界資源處於空閑狀態,允許一個請求進入臨界區的進程立即進入臨界區,以有效利用臨界資源
· 忙則等待:當已有進程處於臨界區時,表明臨界資源正在被訪問,因而其他試圖進入臨界區的進程必須等待,以保證對臨界資源的互斥訪問
· 有限等待:對要求訪問臨界資源的進程,應保證在有限時間內能進入自己的臨界區,以免陷入“死等”狀態
· 讓權等待:當進程不能進入自己的臨界區時,應立即釋放處理機,以免進程陷入“忙等”狀態
(1) 因為系統資源不足。
(2) 進程運行推進的順序不合適。
(1) 互斥條件:一個資源每次只能被一個進程使用。
(2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。
(3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。
(4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。
線程作為調度和分配的基本單位,進程作為擁有資源的基本單位
線程的划分尺度小於進程,使得多線程程序的並發性高
在同一進程中的各個線程,才可以共享該進程所擁有的資源
1、線程與進程的區別?
進程是操作系統分配資源的最小單元,線程是操作系統調度的最小單元。
一個程序至少有一個進程,一個進程至少有一個線程。
2、什么是多線程中的上下文切換?
多線程會共同使用一組計算機上的CPU,而線程數大於給程序分配的CPU數量時,為了讓各個線程都有執行的機會,就需要輪轉使用CPU。不同的線程切換使用CPU發生的切換數據等就是上下文切換。
3、多線程同步和互斥有幾種實現方法,都是什么?
線程同步是指線程之間所具有的一種制約關系,一個線程的執行依賴另一個線程的消息,當它沒有得到另一個線程的消息時應等待,直到消息到達時才被喚醒。
線程互斥是指對於共享的進程系統資源,在各單個線程訪問時的排它性。當有若干個線程都要使用某一共享資源時,任何時刻最多只允許一個線程去使用,其它要使用該資源的線程必須等待,直到占用資源者釋放該資源。線程互斥可以看成是一種特殊的線程同步。
線程間的同步方法大體可分為兩類:用戶模式和內核模式。顧名思義,內核模式就是指利用系統內核對象的單一性來進行同步,使用時需要切換內核態與用戶態,而用戶模式就是不需要切換到內核態,只在用戶態完成操作。
用戶模式下的方法有:原子操作(例如一個單一的全局變量),臨界區。內核模式下的方法有:事件,信號量,互斥量。
21、java如何實現多線程之間的通訊和協作?
中斷和共享變量
23、volatile有什么用?能否用一句話說明下volatile的應用場景?
volatile保證內存可見性和禁止指令重排。
volatile用於多線程環境下的單次操作(單次讀或者單次寫)。
25、在java中wait和sleep方法的不同?
最大的不同是在等待時wait會釋放鎖,而sleep一直持有鎖。Wait通常被用於線程間交互,sleep通常被用於暫停執行。
直接了解的深入一點吧:


在Java中線程的狀態一共被分成6種:
初始態:NEW
創建一個Thread對象,但還未調用start()啟動線程時,線程處於初始態。
運行態:RUNNABLE
在Java中,運行態包括就緒態和運行態。
就緒態該狀態下的線程已經獲得執行所需的所有資源,只要CPU分配執行權就能運行。所有就緒態的線程存放在就緒隊列中。
運行態獲得CPU執行權,正在執行的線程。由於一個CPU同一時刻只能執行一條線程,因此每個CPU每個時刻只有一條運行態的線程。
阻塞態
當一條正在執行的線程請求某一資源失敗時,就會進入阻塞態。而在Java中,阻塞態專指請求鎖失敗時進入的狀態。由一個阻塞隊列存放所有阻塞態的線程。處於阻塞態的線程會不斷請求資源,一旦請求成功,就會進入就緒隊列,等待執行。PS:鎖、IO、Socket等都資源。
等待態
當前線程中調用wait、join、park函數時,當前線程就會進入等待態。也有一個等待隊列存放所有等待態的線程。線程處於等待態表示它需要等待其他線程的指示才能繼續運行。進入等待態的線程會釋放CPU執行權,並釋放資源(如:鎖)
超時等待態
當運行中的線程調用sleep(time)、wait、join、parkNanos、parkUntil時,就會進入該狀態;它和等待態一樣,並不是因為請求不到資源,而是主動進入,並且進入后需要其他線程喚醒;進入該狀態后釋放CPU執行權 和 占有的資源。與等待態的區別:到了超時時間后自動進入阻塞隊列,開始競爭鎖。
終止態
線程執行結束后的狀態。
注意:
wait()方法會釋放CPU執行權 和 占有的鎖。
sleep(long)方法僅釋放CPU使用權,鎖仍然占用;線程被放入超時等待隊列,與yield相比,它會使線程較長時間得不到運行。
yield()方法僅釋放CPU執行權,鎖仍然占用,線程會被放入就緒隊列,會在短時間內再次執行。
wait和notify必須配套使用,即必須使用同一把鎖調用;
wait和notify必須放在一個同步塊中調用wait和notify的對象必須是他們所處同步塊的鎖對象。
