Java併發編程之線程的中止

簡介

通常狀況下,線程執行完成後就會結束,但有的時候咱們可能須要在它正常執行完成前就中止它,能夠考慮使用如下三種方法:java

  1. 使用Thread中的stop方法,這個方法已經被標爲已廢棄,不推薦使用,緣由是stop方法會當即終止線程並釋放持有的鎖,在多線程的狀況下可能會致使數據不一致的問題。多線程

  2. 自定義一個標誌,經過修改這個標誌的值來讓線程判斷是否須要退出。ide

  3. 使用線程中斷機制。線程

後面兩種方法有點相似,都是經過給線程發一個通知,而後讓線程去判斷是否能夠結束,而不是像stop方法那樣暴力的終止線程,下面介紹下後兩種方法的使用和區別。code

使用自定義標誌中止線程

這裏定義了一個變量flag,主線程會在3秒後將flag設置爲false,當flag爲false的時候,run方法裏面的循環就會結束,線程也就中止了。it

public class MyThread extends Thread{
    volatile boolean flag = true;

    @Override
    public void run() {
        while (flag){
            System.out.println("do something...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(3000);
        myThread.flag = false;
    }
}

使用線程中斷機制中止線程

線程中斷有關的三個方法:io

  1. interrupt(),中斷線程。
  2. isInterrupted(),判斷線程是否被中斷。
  3. interrupted,Thread類的靜態方法,判斷線程是否被中斷,並清除中斷狀態。

這種方式與前面那種方式很相似,只是由判斷flag變爲判斷線程是否被中斷。class

public class MyThread extends Thread{

    @Override
    public void run() {
        while (!isInterrupted()){
            System.out.println("do something...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(3000);
        myThread.interrupt();
    }
}

自定義標誌和線程中斷機制的區別

前面介紹的兩種方式使用起來很是的相似,可是中斷機制要更強,由於當循環體內出現了Thread.sleep()或者wait()這樣的操做時,自定義標誌的方式就只能等阻塞結束。而這兩個方法是能夠響應中斷的。變量

1.主線程在3秒後更改flag狀態,可是線程還處於sleep()阻塞中,須要等到sleep()時間結束也就是10秒後線程才中止。循環

public class MyThread extends Thread{
    volatile boolean flag = true;

    @Override
    public void run() {
        while (flag){
            try {
                Thread.sleep(10000);
            }catch (InterruptedException ex){
                ex.printStackTrace();
            }
            System.out.println("do something...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(3000);
        myThread.flag = false;
    }
}

2.處於sleep()阻塞中的線程若是被中斷就會拋出InterruptedException異常,此時它會清除中斷標記,因此須要捕獲該異常,並在異常處理中再次設置中斷標記。

public class MyThread extends Thread{

    @Override
    public void run() {
        while (!isInterrupted()){
            try {
                Thread.sleep(10000);
            }catch (InterruptedException ex){
                //從新設置中斷標記
                interrupt();
            }
            System.out.println("do something...");
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread myThread = new MyThread();
        myThread.start();
        Thread.sleep(3000);
        myThread.interrupt();
    }
}
相關文章
相關標籤/搜索