Java 死鎖(DeadLock)例項分析和預防[base jdk8]

FeelTouch發表於2018-02-03

synchronized實現死鎖

/**
 * Created by Administrator on 2018/2/3.
 */
public class SynchronizedDeadLockTest {

    static Object src1 = new Object();
    static Object src2 = new Object();

    public static void main(String[] args) {
        Thread t1 = new Thread(new DeadARunnable(), "t1");
        Thread t2 = new Thread(new DeadBRunnable(), "t2");
        t1.start();
        t2.start();
    }
}

class DeadARunnable implements Runnable {
    @Override
    public void run() {
        synchronized (SynchronizedDeadLockTest.src1){
            try{
                System.out.println(Thread.currentThread().getName()+" get src1 ing!");
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName()+" after sleep 500ms!");
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" need src2 and waiting!");
            /**
             * Thread t2 try get source src2 when locked source src1
             */
            synchronized (SynchronizedDeadLockTest.src2){
                System.out.println(Thread.currentThread().getName()+" get src2 ing!");
            }
        }
    }
}

class DeadBRunnable implements Runnable {
    @Override
    public void run() {
        synchronized (SynchronizedDeadLockTest.src2){
            try{
                System.out.println(Thread.currentThread().getName()+" get src2 ing!");
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName()+" after sleep 500ms!");
            }catch(Exception e){
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+" need src1 and waiting!");
            /**
             * Thread t1 try get source src1 when locked source src2
             */
            synchronized (SynchronizedDeadLockTest.src1){
                System.out.println(Thread.currentThread().getName()+" get src1 ing!");
            }
        }
    }
}

飢餓

指的執行緒無法訪問到它需要的資源而不能繼續執行的一種狀態。引發飢餓最常見資源就是CPU時鐘週期。雖然在Thread API中由指定執行緒優先順序的機制,但是隻能作為作業系統進行執行緒排程的一個參考,作業系統在進行執行緒排程是平臺無關的,會盡可能提供公平的、活躍性良好的排程,那麼即使在程式中指定了執行緒的優先順序,也有可能在作業系統進行排程的時候對映到了同一個優先順序。通常情況下,不要區修改執行緒的優先順序,一旦修改程式的行為就會與平臺相關,並且會導致飢餓問題的產生。在程式中使用的Thread.yield或者Thread.sleep表明該程式試圖客服優先順序調整問題,讓優先順序更低的執行緒擁有被CPU排程的機會。


活鎖

指的是執行緒不斷重複執行相同的操作,但每次操作的結果都是失敗的。儘管這個問題不會阻塞執行緒,但是程式也無法繼續執行。活鎖通常發生在處理事務訊息的應用程式中,如果不能成功處理這個事務那麼事務將回滾整個操作。解決活鎖的辦法是在每次重複執行的時候引入隨機機制,這樣由於出現的可能性不同使得程式可以繼續執行其他的任務。

相關文章