多線程: 線程的生命週期及死鎖的解決方法

線程的生命週期分爲以下幾種情況

1:當創建一個線程的時候: New的狀態

2:執行start: 就緒狀態,這個時候還沒有運行,需要分配CPU的資源才能運行

3: 運行狀態: 該線程被調度了分配到了CPU資源

4:如果一切正常,線程裏的代碼執行完,銷燬狀態(Terminated);

4.1: 如果在運行時執行了wait()這個時候就進入了等待狀態,但是這個狀態即會釋放CPU執行權,如果有鎖也會釋放鎖

4.2: 如果在運行時執行了sleep(1000),進入等待超時狀態 這個狀態只會釋放CPU執行權,不會釋放鎖

4.3: 如果在運行時執行了yelid(), 或者CPU執行權被搶了,這個時候又會回到第二個狀態,就緒.

4.5: 如果線程處在4.2狀態,這個時候執行interrupt方法,這個時候就會進入到2的狀態也就是就緒狀態

4.5: 如果線程處在4.1狀態,這個時候執行notify或者notifyAll,線程會進入到2的狀態也就是就緒狀態

4.6:如果線程中需要獲取synchronized鎖,進入到阻塞狀態,獲取到了鎖進入到就緒狀態.

4.7:如果線程處在4.2狀態,等時間到,這個時候會進入到2的狀態也就是就緒狀態

 

Java發生死鎖的條件

1: 多個線程(Thread)操作多個資源(Resource)  Thread要大於Resource 而且它們要>=2

2: 爭奪資源的順序不對.

3: 拿到了資源死不放手.

舉個例子

    public static void diedLocd(){
        Object one = new Object();
        Object two = new Object();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (one){
                    System.out.println("get one");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (two){
                        System.out.println("get two");
                    }
                }
            }
        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (two){
                    System.out.println("get two");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (one){
                        System.out.println("get onw");
                    }
                }
            }
        }).start();
    }

上面這種情況肯定死鎖,

解決方法 :

1: 上面是爭奪資源順序不對,把第一個鎖都換成one 第二個變成two肯定不會

2: 上面死鎖是一直拿到鎖不釋放,我們可以採用Lock裏的tryLock方法,但是爲了避免活鎖,最好做一個小點的延時

代碼如下

    public static void unDiedLocd() {
        Lock one = new ReentrantLock();
        Lock two = new ReentrantLock();
        Random random = new Random();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (one.tryLock()) {
                        System.out.println("get one");

                        try {
                            if (two.tryLock()) {
                                try {
                                    System.out.println("get two");
                                    break;
                                } finally {
                                    two.unlock();
                                }
                            }
                        } finally {
                            one.unlock();
                        }
                    }
                    try {
                        Thread.sleep(random.nextInt(3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (two.tryLock()) {
                        System.out.println("get one");

                        try {
                            if (one.tryLock()) {
                                try {
                                    System.out.println("get two");
                                    break;
                                } finally {
                                    one.unlock();
                                }
                            }
                        } finally {
                            two.unlock();
                        }
                    }
                    try {
                        Thread.sleep(random.nextInt(3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();
    }

 

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