1.7 JAVA多線程編程——停止線程

1.7 停止線程

首先Thread.stop()方法可以停止一個線程,但是它不安全,而且也是被廢棄的,不要去使用它。
大多數停止一個線程的操作是使用Thread.interrupt()方法,該方法不會終止一個正在運行的線程,還需要加入一個判斷纔可以完成線程的停止。
Java中有以下3種方法可以終止正在運行的線程:
1)使用退出標誌,使線程正常退出,即run()方法完成後線程終止。
2)使用stop()方法強行終止線程,但是不推薦使用這個方法,因爲stop和suspend及resume一樣,都是作廢的方法,結果不可預測。
3)使用interrupt()方法中斷線程。

1.7.1 interrupt()方法停止線程

調用interrupt()方法僅僅是在當前線程中打了一個停止的標記,並不是真的停止線程。這個比較簡單,在run()方法中寫個for循環然後在main方法中調用一下類對象的interrupt()方法看看for循環有沒有停止就比較直觀了。

1.7.2 判斷線程的停止狀態

這裏有兩個方法:(1) interrupted() (2)isInterrupted()
兩者聲明分別爲:1.public static boolean interrupted(). 2.public boolean isInterrupted()
其中interrupted()方法是測試當前線程是否已經是中斷狀態,執行後具有將狀態標誌清除爲false的功能。
isInterrupted()方法是測試線程Thread對象是否已經是中斷狀態,但不清除狀態標誌。

具體比較可以看以下代碼:

public class Thread_172 {
public static void main(String[] args) {
    Thread.currentThread().interrupt();
    System.out.println("是否停止了1? ==》"+Thread.interrupted());
    System.out.println("是否停止了2? ==》"+Thread.interrupted());
    System.out.println("====end====");
}

}

輸出爲:
是否停止了1? ==》true
是否停止了2? ==》false
====end====

public class Thread_172_2 {
    static class MyThread extends Thread{
        public  void run(){
            super.run();
            for(int i=0;i<900000;i++){
                System.out.println("i="+(i+1));
            }
        }
    }
public static void main(String[] args) {
    try{
        MyThread thread = new MyThread();
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
        System.out.println("--------是否停止1?==》 "+thread.isInterrupted());
        System.out.println("--------是否停止2?==》 "+thread.isInterrupted());
    }catch(InterruptedException e){
        System.out.println("main catch");
        e.printStackTrace();
    }
    System.out.println("~~end~~");
     } 
   }


i=163187
i=163188
--------是否停止1?==》 true
--------是否停止2?==》 true
~~end~~
i=163189
i=163190
i=163191

1.7.3(4) 用異常法停止線程以及在sleep()時停止線程

如果在run()方法中加入if(this.interrupted()){
throw new InterruptedException();
}
然後用try catch包裹住,就相當於用異常法停止了線程,這也是比較常用的方法,也就是避免了for循環後面的語句被運行,在遇到拋出異常後直接進入catch語句塊。

來看個代碼

public class Thread_174_2 {

static class MyThread extends  Thread {
    public void run(){
        super.run();
        try{
            for(int i=0;i<10000;i++){
                System.out.println("i="+(i+1));
            }
            System.out.println("run begin");
            Thread.sleep(20000);
            System.out.println("run end");
        }catch (InterruptedException e){
            System.out.println("先停止,再遇到了sleep!進入catch!"+this.isInterrupted());
            e.printStackTrace();
        }
    }
}
public static void main(String[] args) {
    MyThread thread = new MyThread();
    thread.start();
    thread.interrupt();
    System.out.println("-------end!");
}
}
輸出如下:
i=9997
i=9998
i=9999
i=10000
run begin
先停止,再遇到了sleep!進入catch!false
java.lang.InterruptedException: sleep interrupted
 at java.lang.Thread.sleep(Native Method)
 at Thread_174_2$MyThread.run(Thread_174_2.java:14)


for循環後的幾句沒有被運行。

再來看看先sleep再打斷

public class Thread_174 {
static class MyThread extends  Thread {
    public void run(){
        try{
            System.out.println("run begin");
            Thread.sleep(20000);
            System.out.println("run end");
        }catch (InterruptedException e){
            System.out.println("在沉睡中被停止!進入catch!"+this.isInterrupted());
            e.printStackTrace();
        }
    }
}

public static void main(String[] args) {

    try {
        MyThread thread = new MyThread();
        thread.start();
        Thread.sleep(200);
        thread.interrupt();
    } catch (InterruptedException e) {
        System.out.println("main catch");
        e.printStackTrace();
    }

    System.out.println("end!");
}

}

輸出如下:
run begin
end!
在沉睡中被停止!進入catch!false
Disconnected from the target VM, address: ‘127.0.0.1:61778’, transport: ‘socket’
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at Thread_174$MyThread.run(Thread_174.java:9)

即當我們調用了sleep()方法後,又對其進行中斷,那麼會拋出異常進入catch語句,並且清除停止狀態值。

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