Java 實現執行緒死鎖

segmentfault發表於2016-02-20

概述

春節的時候去面試了一家公司,筆試題裡面有一道是使用簡單的程式碼實現執行緒的‘死鎖’,當時沒有想到這道題考的是Synchronized關鍵字,於是自己定義了兩個資源模擬了一下。後面想想腸子都悔青了,於是自己在電腦上敲了一遍,同時也是對自己的一個提醒,基礎功夫還不夠紮實。

Synchronized關鍵字

Java語言的關鍵字,當它用來修飾一個方法或者一個程式碼塊的時候,能夠保證在同一時刻最多隻有一個執行緒執行該段程式碼。

  1. 當兩個併發執行緒訪問同一個物件object中的這個synchronized(this)同步程式碼塊時,一個時間內只能有一個執行緒得到執行。另一個執行緒必須等待當前執行緒執行完這個程式碼塊以後才能執行該程式碼塊。
  2. 然而,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,另一個執行緒仍然可以訪問該object中的非synchronized(this)同步程式碼塊。
  3. 尤其關鍵的是,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,其他執行緒對object中所有其它synchronized(this)同步程式碼塊的訪問將被阻塞。
  4. 第三個例子同樣適用其它同步程式碼塊。也就是說,當一個執行緒訪問object的一個synchronized(this)同步程式碼塊時,它就獲得了這個object的物件鎖。結果,其它執行緒對該object物件所有同步程式碼部分的訪問都被暫時阻塞。
  5. 以上規則對其它物件鎖同樣適用.

程式碼示例

package test160118;

public class TestSynchronized {
    public static void main(String[] args) {
        Sy sy = new Sy(0);
        Sy sy2 = new Sy(1);
        sy.start();
        sy2.start();
    }
}

class Sy extends Thread {
    private int flag ;

    static Object x1 = new Object();
    static Object x2 = new Object();

    public Sy(int flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        System.out.println(flag);
        try {
            if (flag == 0) {
                synchronized (x1) {
                    System.out.println(flag+"鎖住了x1");
                    Thread.sleep(1000);
                    synchronized (x2) {
                        System.out.println(flag+"鎖住了x2");
                    }
                    System.out.println(flag+"釋放了x1和x2");
                }
            }
            if(flag == 1) {
                synchronized (x2) {
                    System.out.println(flag+"鎖住了x2");
                    Thread.sleep(1000);
                    synchronized (x1) {
                        System.out.println(flag+"鎖住了x1");
                    }
                    System.out.println(flag+"釋放了x1和x2");
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

總結

總之說多了都是淚,關鍵不是我不會而是我沒有想到它考的都是這個。也不知道面試過沒過,有點方。後面會陸陸續續把之前面試時答得不是很好的幾道題寫成專欄的。

相關文章