java線程中斷的辦法


中斷線程相關的方法

中斷線程有一些相應的方法,這里列出來一下。

注意,如果是Thread.method(),則代表是靜態方法。如果是thread.method()則代表着是類方法

  • void thread.stop()
    這個方法能中斷正在運行的線程,但是已經不推薦使用了,在將來的版本或許棄用,因為強行中斷運行中的線程,是不安全的。

  • void thread.interrupt()
    如果正在運行wait(),sleep(),join()這三個方法阻塞了線程,那么將會使得線程拋出InterruptedException異常,這是一個中斷阻塞的過程。如果是其它的正在運行的狀態,那么將不會有任何影響,也不會中斷線程,或者拋出異常,只會會打上一個中斷線程的標志,是否中斷線程,將由程序控制。

  • boolean thread.isInterrupted()
    它會獲取當前線程的標志,如果之前調用過thread.interrupt(),那么它的返回值是true。它的作用就是返回該線程是否有中斷標志。多次調用這個方法的結果是一樣的。

  • void Thread.interrupted()
    與前面的方法不一樣的是,這是一個靜態方法,代表着不需要拿到線程對象就可以直接執行,所以它的作用是返回當前線程是否有中斷標志。但是它的區別是,當調用這個方法之后,會清除程序的中斷標志,就是如果當前線程已中斷,第一次調用這個方法的返回值是true,第二次調用這個方法的返回值為false,因為調用方法時,會清除它的中斷標志。

中斷線程

for循環標記退出

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak implements Runnable {

    @Override
    public void run() {
        for(int i = 0 ; i < 10000 ; i ++){
            boolean interruped = Thread.currentThread().isInterrupted();
            if(interruped){
                //有中斷標記,中斷
                break;
            }
            System.out.println(i);
        }

        System.out.println("over");
    }


    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new ThreadBreak());
        t.start();
        Thread.sleep(1);

        t.interrupt();
    }
}

打印結果如下

44
45
46
47
over

阻塞的退出線程

只要是在運行wait(),sleep(),join()的方法,它就會聲明一個InterruptedException異常,也就是意味着這些方法並不是一定能執行完成,因為當調用線程的interrupt()方法時,就會中斷這個阻塞的辦法,從而進入到異常中,代碼如下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak2 implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(20000);
            System.out.println("這段話不會輸出");
        } catch (InterruptedException e) {
            //如果在sleep()的過程中調用了interrupt()方法,就會進入這里,因為會強行中斷sleep()
            
            //這里打印出來的中斷標記為false,因為只要進入了InterruptedException異常,中斷標記就會被清除掉
            System.out.println("中斷標記為:" + Thread.currentThread().isInterrupted());
            System.out.println("輸出異常");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new ThreadBreak2());
        t.start();

        Thread.sleep(100);

        t.interrupt();

        System.out.println("over");
    }
}

打印結果如下

over
中斷標記為:false
輸出異常
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.xiaojiezhu.thread.ThreadBreak2.run(ThreadBreak2.java:10)
	at java.lang.Thread.run(Thread.java:748)

注意:因為只要進入了InterruptedException異常,中斷標記就會被清除掉

這里會衍生出另一種情況,就是如果在進入阻塞方法之前,就有了中斷標記呢?會發生什么,就如下的代碼:

for(int i = 0 ; i < 10000 ; i ++){
    System.out.println(i);
}
try {
    System.out.println("開始sleep");
    Thread.sleep(20000);
    System.out.println("結束sleep");

} catch (InterruptedException e) {
    e.printStackTrace();
}

實際上它會先執行完上面的for循環,因為for循環中是無法中止的,在進入sleep()的時候,瞬間就拋出異常

完整的測試代碼如下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak3 implements Runnable {

    @Override
    public void run() {
        for(int i = 0 ; i < 10000 ; i ++){
            System.out.println(i);
        }
        try {
            System.out.println("開始sleep");
            Thread.sleep(20000);
            System.out.println("結束sleep");

        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Thread thread = new Thread(new ThreadBreak3());
        thread.start();

        thread.interrupt();
    }
}

打印結果如下

9997
9998
9999
開始sleep
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.xiaojiezhu.thread.ThreadBreak3.run(ThreadBreak3.java:15)
	at java.lang.Thread.run(Thread.java:748)

使用stop()方法停止線程

thread.stop()方法是一個不安全的方法,已經不推薦使用了,但是在目前的代碼中,還能正常使用,我們不推薦這樣使用,但是這里介紹一下

package com.xiaojiezhu.thread;

/**
 * @author xiaojie.zhu
 */
public class ThreadBreak4 implements Runnable {
    @Override
    public void run() {
        System.out.println("進入線程");
        try {
            Thread.sleep(20000);
            System.out.println("結束線程");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        Thread t  = new Thread(new ThreadBreak4());
        t.start();
        try {
            Thread.sleep(200);

            t.stop();

            System.out.println("over");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

打印結果如下

進入線程
over


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM