Java-死鎖

死鎖定義:死鎖是指兩個或兩個以上的進程在執行過程當中,因爲競爭資源或者因爲彼此通訊而形成的一種阻塞現象,若無外力做用,它們都將沒法推動下去,此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在相互等待的進程稱爲死鎖進程。ide

例子:哲學家進餐問題函數

死鎖產生的必要條件:this

  1. 互斥條件:進程對所分配到的資源不容許其餘進程進行訪問,若其餘進程訪問該資源,只能等待,直到佔有該資源的進程使用完後釋放該資源。
  2. 請求和保持:進程得到必定資源後,能夠對其餘資源發出獲取請求,但同時對本身已經得到的資源保持不放
  3. 不可剝奪條件:進程已經得到的資源,在未完成使用以前,不能夠被剝奪,只能在使用完成以後本身釋放。
  4. 循環等待:進程發生死鎖後,必然存在一個進程-資源之間環形鏈。

破壞產生死鎖的任何一個必要條件均可以消除死鎖現象。spa

寫一個簡單的死鎖程序:線程

package com.fpc.Test;
class thread1 implements Runnable {
    private DeadLock deadlock;
    
    //構造函數
    public thread1( DeadLock deadlock ) {
        this.deadlock = deadlock;
    }
    
    @Override
    public void run( ) {
        try {
            deadlock.lock1toLock2();
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }
}

class thread2 implements Runnable {
    private DeadLock deadlock;
    
    //構造函數
    public thread2( DeadLock deadlock ) {
        this.deadlock = deadlock;
    }
    
    @Override
    public void run( ) {
        try {
            deadlock.lock2toLock1();
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }
}

public class DeadLock {
    private Object lock1 = new Object();
    private Object lock2 = new Object();
    
    public void lock1toLock2() {
        synchronized( lock1 ) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized( lock2 ) {
                System.out.println("lock1toLock2 end.....");
            }
        }
    }
    
    public void lock2toLock1() {
        synchronized( lock2 ) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized( lock1 ) {
                System.out.println("lock2toLock1 end.....");
            }
        }
    }
    
    public static void main( String[] args ) {
        DeadLock d = new DeadLock();
        thread1 t1 = new thread1(d);
        thread2 t2 = new thread2(d);
        Thread th1 = new Thread(t1);
        Thread th2 = new Thread(t2);
        th1.start();
        th2.start();
    }
}

怎麼去分析死鎖:設計

先用jps命令查看虛機中運行的Java線程的pid:3d

而後根據pid 去查看 jstack pid:code

避免死鎖的方式對象

1.設計時考慮清楚鎖的順序,儘可能減小嵌套的加鎖交互數量blog

2.死鎖產生的緣由是資源的循環等待,那麼給獲取鎖加個時間限制,超過必定的時間尚未獲取到對象的鎖,那麼就釋放已經獲取的對象的鎖。固然synchronized是沒法作到的,能夠用可重入鎖ReentrantLock

 

針對上面的程序能夠這麼改:

public void lock1toLock2() throws InterruptedException {
        if (lock1.tryLock(3000, TimeUnit.MILLISECONDS)){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                if ( lock2.tryLock(3000, TimeUnit.MICROSECONDS) ) {
                    System.out.println("lock1toLock2 end.....");
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
      }
    }

運行再次查看jps:能夠看到沒有出現DeadLock線程了,嗯,不會出現死鎖了

相關文章
相關標籤/搜索