線程之Interrupt的使用與線程高併發的理解

紅色的表示主線程的while(){}代碼塊,

藍色的表示子線程的異常執行,

黑色的表示子線程代碼段:j++;的執行;

 

#爲什麼產生異常#java.lang.InterruptException#當父線程(外部線程)的sleep時間小於子線程的sleep時間,程序就會出現異常,但是並不影響程序的執行(可能因爲try-catch吧)。

當你不想看到異常時,可以把外部線程(DemoFather)第一次sleep的時間改成大於內部線程的sleep時間即可消除異常。

 

public class DemoFather {
    public static void main(String[] args) {
        InThreaad inThread =new InThreaad();
        Thread outThread  = new Thread(inThread);
        System.out.println("DemoFather線程調用start方法之前的狀態:" + outThread.getState());
        outThread.start();
        System.out.println("DemoFather線程調用start方法之後的狀態:" + outThread.getState());

        try {
            Thread.sleep(100);   //當父線程(outThread線程/DemoFather線程)的sleep時間100 < 子線程(inThread/子線程)
//sleep時間500時,inThread會因爲outThread執行了interrupt方法,進而產生java.lang.InterruptException。
        } catch (InterruptedException e) {
            e.printStackTrace();
        } //該sleep的作用是爲了證明interrupt終止的作用(事實上,它只是起到了喚醒子線程的作用)。
        
        inThread.printData();//打印出內部InThread的synchronized前一半;
        outThread.interrupt();  //喚醒子線程,CPU調度去執行內部線程“未完成的部分”(synchronized的另一半)。
        
        while (outThread.isAlive()) {
            //主線程等待子線程執行完synchronized內的代碼;
            inThread.printData();
        }
        inThread.printData();
        System.out.println("通過isAlive()等待子線程的喚醒、執行,讓其執行InThread線程,:" + outThread.getState().name());
        System.out.println("DemoFather線程調用interrupt方法之後:" + outThread.getState().name());
        inThread.printData();
    }
}

 

public class InThreaad implements Runnable{
        int i,j;

        public void run() {
            System.out.println("線程Sun進入runnable狀態:" + Thread.currentThread().getState());
            synchronized (this){
                System.out.println("線程Sun進入synchronized狀態:" + Thread.currentThread().getState());
                i++;
                try {
                    Thread.sleep(500);      //java.lang.InterruptException

//當父線程(outThread線程/DemoFather線程)的sleep時間100 < 子線程(inThread/子線程)的sleep時間500時,
//inThread會因爲outThread執行了interrupt方法,進而產生java.lang.InterruptException。

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                j++;
            }
            System.out.println("線程Sun進入終止狀態:" + Thread.currentThread().getState());
        }

        public void printData() {
            System.out.println("i = " + i + "/r  j = " + j);
        }
}

執行截圖:

當主線程調用interrupt後,子線程將依次產生4個異常(此時的主線程不會因爲子線程的喚醒而停止執行,因爲它打印出了i,j值),隨着子線程的四個異常完成後,子線程被喚醒,繼續執行其代碼(j++;)。

 

-續上圖

1,2,3,4的過程表明了主線程和子線程的併發執行(通過2,3感覺主線程的執行速度比子線程的速度快啊[困惑])。

代碼執行過程描述:

程序執行入口main方法:

1.創建內部線程,inThread = new InThreaad();

2.根據inThreaad創建外部線程,outThread = new Thread(inThread);

3.依次執行main方法的代碼 -> 直到當前線程Thread(即:outThread)執行了sleep(100);

4.CPU調度跳轉執行InThreaad -> 依次執行InThread中的代碼:run();  ->  直到執行到當前線程(inThread)sleep時;

5.CPU調度跳轉執行OutThreaad線程 -> 依次執行OutThread中的代碼:printData(); -> interrupt(); 

6.CPU調度跳轉執行InThreaad(產生4次異常後,異常見下截圖) -> 依次執行InThread中的代碼:j++;

7.InThread線程內的方法都執行完成後,再次執行OutThread線程剩餘代碼:printData();

8.end

關於第6步:

 

 

此文如有不妥,請給予指點,感謝!

 

 

 

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