java多線程死鎖

進程(線程)同步的基本概念

進程之間的制約關係

1. 直接制約關係(進程同步)安全

這個關係主要源於進程合做,例如,有一個輸入進程A經過單緩衝向進程B提供數據,當該緩衝空時,進程B由於不能得到所需數據而被阻塞,A將數據送入緩衝區時邊將B喚醒。ide

2. 間接制約關係(進程互斥)this

這種關係主要源於資源共享,好比有倆個進程A,B都在競爭打印機資源,若是在A提出打印請求時,系統已將打印機分配給B,則進程A進入阻塞狀態,等進程B釋放打印機後,才能喚醒Aspa

進程同步遵循的規則

1空閒讓進線程

當無進程進入臨界區時,相應的臨界資源處於空閒狀態,於是容許一個請求進入臨界區的進程當即進入本身的臨界區。code

2忙則等待blog

當已有進程進入本身的臨界區時,即相應的臨界資源正被訪問,於是其它試圖進入臨界區的進程必須等待,以保證進程互斥地訪問臨界資源。進程

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();
        
    }
}
相關文章
相關標籤/搜索