標籤:static 存在 過程 操作 class todo 接下來 輸入 線程
進程(線程)同步的基本概念進程之間的制約關係
1. 直接制約關係(進程同步)
這個關係主要源於進程合作,例如,有一個輸入進程A通過單緩衝向進程B提供資料,當該緩衝空時,進程B因為不能獲得所需資料而被阻塞,A將資料送入緩衝區時邊將B喚醒。
2. 間接制約關係(進程互斥)
這種關係主要源於資源共用,比如有倆個進程A,B都在競爭印表機資源,如果在A提出列印請求時,系統已將印表機分配給B,則進程A進入阻塞狀態,等進程B釋放印表機後,才能喚醒A
進程同步遵循的規則
1空閑讓進
當無進程進入臨界區時,相應的臨界資源處於空閑狀態,因而允許一個請求進入臨界區的進程立即進入自己的臨界區。
2忙則等待
當已有進程進入自己的臨界區時,即相應的臨界資源正被訪問,因而其它試圖進入臨界區的進程必須等待,以保證進程互斥地訪問臨界資源。
3有限等待
對要求訪問臨界資源的進程,應保證進程能在有限時間進入臨界區,以免陷入“饑餓”狀態。
4讓權等待
當進程不能進入自己的臨界區時,應立即釋放處理機,以免進程陷入忙等。
死結的概念一. 什麼是死結?
如果一個進程集合裡面的每個進程都在等待這個集合中的其他一個進程(包括自身)才能繼續往下執行,若無外力他們將無法推進,這種情況就是死結,處於死結狀態的進程稱為死結進程
二. 死結產生的原因?
1.因競爭資源發生死結 現象:系統中供多個進程共用的資源的數目不足以滿足全部進程的需要時,就會引起對諸資源的競爭而發生死結現象
(1)可剝奪資源和不可剝奪資源:可剝奪資源是指某進程在獲得該類資源時,該資源同樣可以被其他進程或系統剝奪,不可剝奪資源是指當系統把該類資源分派給某個進程時,不能強制收回,只能在該進程使用完成後自動釋放
(2)競爭不可剝奪資源:系統中不可剝奪資源的數目不足以滿足諸進程啟動並執行要求,則發生在運行進程中,不同的進程因爭奪這些資源陷入僵局。
舉例說明: 資源A,B; 進程C,D
資源A,B都是不可剝奪資源:一個進程申請了之後,不能強制收回,只能進程結束之後自動釋放。記憶體就是可剝奪資源
進程C申請了資源A,進程D申請了資源B。
接下來C的操作用到資源B,D的資源用到資源A。但是C,D都得不到接下來的資源,那麼就引發了死結。
(3)競爭臨時資源
2.進程推進順序不當發生死結
三. 產生死結的四個必要條件?
(1)互斥條件:進程對所分配到的資源不允許其他進程進行訪問,若其他進程訪問該資源,只能等待,直至佔有該資源的進程使用完成後釋放該資源
(2)請求和保持條件:進程獲得一定的資源之後,又對其他資源發出請求,但是該資源可能被其他進程佔有,此事請求阻塞,但又對自己獲得的資源保持不放
(3)不可剝奪條件:是指進程已獲得的資源,在未完成使用之前,不可被剝奪,只能在使用完後自己釋放
(4)環路等待條件:是指進程發生死結後,必然存在一個進程--資源之間的環形鏈
四. 處理死結的基本方法
1.預防死結:通過設定一些限制條件,去破壞產生死結的必要條件
2.避免死結:在資源分派過程中,使用某種方法避免系統進入不安全的狀態,從而避免發生死結
3.檢測死結:允許死結的發生,但是通過系統的檢測之後,採取一些措施,將死結清除掉
4.解除死結:該方法與檢測死結配合使用
因為競爭資源產生死結執行個體:
class DeadLock extends Thread{ public DeadLock(boolean sign,String str) { super(str); this.sign = sign; } private boolean sign = false; private static Object objA = new Object(); private static Object objB = new Object(); @Override public void run() { while(true){ if(sign){ synchronized (objA) { System.out.println(Thread.currentThread().getName()+"獲得資源A"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (objB) { System.out.println(Thread.currentThread().getName()+"獲得資源B"); } } }else { synchronized (objB) { System.out.println(Thread.currentThread().getName()+"獲得資源B"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized (objA) { System.out.println(Thread.currentThread().getName()+"獲得資源A"); } } } } }}public class DeadLockDemo{ public static void main(String[] args) { Thread t1 = new DeadLock(true,"線程一"); Thread t2 = new DeadLock(false,"線程二"); t1.start(); t2.start(); }}
java多線程死結