java實現死鎖代碼

有一天,小李去參加面試,面試官讓他寫一個死鎖的程序,小李思索了一兩分鐘,於是開始了死鎖的代碼:

public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            synchronized (Integer.class) {
                System.out.println("t1 Integer");
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (Long.class) {
                    System.out.println("t1 Long");
                }
            }
        });
        
        t1.start();
        Thread t2 = new Thread(() -> {
            synchronized (Long.class) {
                System.out.println("t2 Long");
                synchronized (Integer.class) {
                    System.out.println("t2 Integer");
                }
            }
        });

        t2.start();
    }

面試官一看,小夥子可以的;面試關就繼續問小夥子,小李啊,如果t2獲取不到時間片,還會死鎖麼?

小李一想,確實如此,能不能改下代碼,一定能讓這段代碼產生死鎖呢?於是小李,又開始了思索,沒過一會呢,小李靈機一動,加了一行代碼,小李說,這樣就一定會產生死鎖了,請看:

public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            synchronized (Integer.class) {
                System.out.println("t1 Integer");
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (Long.class) {
                    System.out.println("t1 Long");
                }
            }
        });
        t1.setDaemon(true);
        t1.start();
        Thread t2 = new Thread(() -> {
            synchronized (Long.class) {
                System.out.println("t2 Long");
                synchronized (Integer.class) {
                    System.out.println("t2 Integer");
                }
            }
        });

        t2.start();
    }

看出有什麼不同了麼?不錯,就是把線程1設置爲守護線程,這樣,只要線程2不運行,守護線程就不會結束,又因爲兩個線程相互持有對象,就會導致程序一直結束不了,從而造成死鎖。

守護線程(即daemon thread),是個服務線程,準確地來說就是服務其他的線程,這是它的作用——而其他的線程只有一種,那就是用戶線程。所以java裏線程分2種,

1、守護線程,比如垃圾回收線程,就是最典型的守護線程。

2、用戶線程,就是應用程序裏的自定義線程。

守護線程,專門用於服務其他的線程,如果其他的線程(即用戶自定義線程)都執行完畢,連main線程也執行完畢,那麼jvm就會退出(即停止運行)——此時,連jvm都停止運行了,守護線程當然也就停止執行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章