1. 程式人生 > 其它 >如何正確中斷 一個執行緒?

如何正確中斷 一個執行緒?

技術標籤:執行緒相關執行緒中斷

如何正確中斷 一個執行緒?

1、通過執行緒提供的方法

  • interrupt
    通過呼叫此方法,系統就會給當前執行緒打上一個中斷標記(true),預設為false,如果其他執行緒中呼叫當前執行緒中的此方法,表示告訴當前執行緒你可以停止了,當前執行緒也可以不理睬繼續執行
  • isInterrupted
    判斷當前執行緒是否被中斷,根據當前執行緒中斷標誌位,做相關的處理
  • Thread.interrupted()
    判斷執行緒是否被中斷,此方法是個靜態方法,跟isInterrupted 不同的是,在判斷的之後會重置中斷標記位為false
1.1 通過Thread 提供的方法來中斷操作(建議使用)
 final Thread thread=new Thread("TestCustomisInterrupted"){
            @Override
            public void run() {
                super.run();
                //預設標誌位 為false
                while (!isInterrupted()){
                    System.out.println(currentThread().getName()+"::::runing......."
); } System.out.println("執行完成::::"+isInterrupted()); //true } }; thread.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } thread.interrupt
();

上邊是個比較簡單的例子,如果當前執行緒執行體裡邊有阻塞方法會是什麼樣的情況:

 final Thread thread=new Thread("TestCustomisInterrupted"){
            @Override
            public void run() {
                super.run();
                //預設標誌位 為false
                while (!isInterrupted()){
                    try {
                        sleep(1000);
                        System.out.println(currentThread().getName()+"::::runing.......");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("執行完成::::"+isInterrupted());  //true
            }
        };

        thread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();

輸入結果

TestCustomisInterrupted::::runing.......
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.example.socket.MyClass$1.run(MyClass.java:78)
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......

會丟擲一箇中斷異常,並且把中斷標誌為重置為false,執行緒不會停止會一直執行,如果想讓程式繼續執行中斷操作可以在,異常裡邊繼續設定中斷操作

利用Thread.interrupted() 靜態方法判斷,如果發生中斷之後,會直接把中斷標記位設定為fasle

  final Thread thread=new Thread("TestCustomisInterrupted"){
            @Override
            public void run() {
                super.run();
                //預設標誌位 為false
                while (!Thread.interrupted()){
                        System.out.println(currentThread().getName()+"::::runing.......");
                }
                System.out.println("執行完成::::"+isInterrupted());  //true
            }
        };

        thread.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();

TestCustomisInterrupted::::runing.......
TestCustomisInterrupted::::runing.......
執行完成::::false

2、通過執行緒自定義欄位去終止執行緒

 class MyRunable implements Runnable{
            boolean isRun=true;

            public boolean isRun() {
                return isRun;
            }

            public void setRun(boolean run) {
                isRun = run;
            }

            @Override
            public void run() {
                while (isRun){
                    System.out.println("::::runing.......");
                }
                System.out.println("執行完成::::"+isRun);  //true
            }
        }
        MyRunable myRunable=new MyRunable();
       new Thread(myRunable).start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myRunable.setRun(false);


::::runing.......
::::runing.......
::::runing.......
::::runing.......
::::runing.......
執行完成::::false

使用自定義標記也可以來停止執行緒,那和執行緒提供的方法有什麼不一樣的呢?
加入我們的run方法邏輯中有阻塞方法時候

        class Mythread extends Thread{
            boolean isRun=true;

            public boolean isRun() {
                return isRun;
            }

            public void setRun(boolean run) {
                isRun = run;
            }
            @Override
            public void run() {
                super.run();
                while (isRun()){
                    try {
                        Thread.sleep(4000);
                        System.out.println("::::runing.......");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("執行完成::::"+isRun());  //true
            }
        }

        Mythread mythread=new Mythread();
        mythread.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        mythread.setRun(false);

加入sleep方法之後,發現線上程休眠的時候呼叫的mythread.setRun(false); 執行緒不會馬上停止,會等到休眠時間到了執行完run方法之後,才會停止

3、使用執行緒的 stop、suspend、resume 方法

以上三個是thread 提供的方法,但是現在被標註過期,不建議 使用,是因為使用以上方法,停止執行緒系統不會釋放執行緒所佔有的資源,因為沒有給執行緒釋放資源的機會和時間,會引起其他問題,所以不建議使用。