最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java中使用interrupt通知線程停止詳析

 更新時(shí)間:2022年09月23日 09:22:35   作者:_燈火闌珊處  
這篇文章主要介紹了java中使用interrupt通知線程停止詳析,文章介紹的是使用interrupt來通知線程停止運(yùn)行,而不是強(qiáng)制停止,詳細(xì)內(nèi)容需要的小伙伴可以參考一下

前言:

使用 interrupt 來通知線程停止運(yùn)行,而不是強(qiáng)制停止!

普通情況停止線程

public class RightWayStopThreadWithoutSleep implements Runnable {

    @Override
    public void run() {
        int num = 0;
        while (!Thread.currentThread().isInterrupted() && num <= Integer.MAX_VALUE / 2) {
            if (num % 10000 == 0) {
                System.out.println(num + "是1W的倍數(shù)");
            }
            num++;
        }
        System.out.println("任務(wù)運(yùn)行結(jié)束!");
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadWithoutSleep());
        thread.start();
        // 等待1s
        Thread.sleep(1000);
        // 通知停止線程
        thread.interrupt();
    }
}

使用 thread.interrupt() 通知線程停止

但是 線程需要配合

在 while 中使用 Thread.currentThread().isInterrupted() 檢測(cè)線程當(dāng)前的狀態(tài)

運(yùn)行結(jié)果:

……
……
221730000是1W的倍數(shù)
221740000是1W的倍數(shù)
221750000是1W的倍數(shù)
221760000是1W的倍數(shù)
221770000是1W的倍數(shù)
221780000是1W的倍數(shù)
221790000是1W的倍數(shù)
221800000是1W的倍數(shù)
任務(wù)運(yùn)行結(jié)束!

Process finished with exit code 0

在可能被阻塞情況下停止線程

public class RightWayStopThreadWithSleep {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = () -> {
            int num = 0;
            while (num <= 300 && !Thread.currentThread().isInterrupted()) {
                if (num % 100 == 0) {
                    System.out.println(num + "是100的倍數(shù)");
                }
                num++;
            }
            try {
                // 等個(gè)1秒,模擬阻塞
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                System.out.println("線程已停止??!");
                e.printStackTrace();
            }
        };

        Thread thread = new Thread(runnable);
        thread.start();
        // 等待時(shí)間要小于上面設(shè)置的1秒,不然線程都運(yùn)行結(jié)束了,才執(zhí)行到下面的thread.interrupt();代碼
        Thread.sleep(500);
        // 通知停止線程
        thread.interrupt();
    }
}

線程在sleep 1秒的過程中,收到interrupt信號(hào)被打斷,

線程正在sleep過程中響應(yīng)中斷的方式就是拋出 InterruptedException 異常

運(yùn)行結(jié)果:

0是100的倍數(shù)
100是100的倍數(shù)
200是100的倍數(shù)
300是100的倍數(shù)
線程已停止??!
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at stopthreads.RightWayStopThreadWithSleep.lambda$main$0(RightWayStopThreadWithSleep.java:19)
    at java.lang.Thread.run(Thread.java:748)

Process finished with exit code 0

在每次迭代后都阻塞的情況下停止線程

public class RightWayStopThreadWithSleepEveryLoop {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = () -> {
            int num = 0;
            try {
                while (num <= 10000) {
                    if (num % 100 == 0) {
                        System.out.println(num + "是100的倍數(shù)");
                    }
                    num++;
                    // 每次循環(huán)都要等待10毫秒,模擬阻塞
                    Thread.sleep(10);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
        // 5秒后通知停止線程
        Thread.sleep(5000);
        thread.interrupt();
    }
}

當(dāng)每次迭代都會(huì)讓線程阻塞一段時(shí)間的時(shí)候,在 while/for 循環(huán)條件判斷時(shí),

是不需要使用 *Thread.currentThread().isInterrupted() *判斷線程是否中斷的

運(yùn)行結(jié)果:

0是100的倍數(shù)
100是100的倍數(shù)
200是100的倍數(shù)
300是100的倍數(shù)
400是100的倍數(shù)
java.lang.InterruptedException: sleep interrupted

如果將上述代碼中的 try/catch 放在 while 循環(huán)內(nèi):

public class RightWayStopThreadWithSleepEveryLoop {
    public static void main(String[] args) throws InterruptedException {
        Runnable runnable = () -> {
            int num = 0;
            while (num <= 10000) {
                if (num % 100 == 0) {
                    System.out.println(num + "是100的倍數(shù)");
                }
                num++;
                try {
                    // 每次循環(huán)都要等待10毫秒,模擬阻塞
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        Thread thread = new Thread(runnable);
        thread.start();
        // 5秒后通知停止線程
        Thread.sleep(5000);
        thread.interrupt();
    }
}

運(yùn)行結(jié)果:

0是100的倍數(shù)
100是100的倍數(shù)
200是100的倍數(shù)
300是100的倍數(shù)
400是100的倍數(shù)
java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at stopthreads.RightWayStopThreadWithSleepEveryLoop.lambda$main$0(RightWayStopThreadWithSleepEveryLoop.java:18)
    at java.lang.Thread.run(Thread.java:748)
500是100的倍數(shù)
600是100的倍數(shù)
700是100的倍數(shù)
……
……

會(huì)發(fā)現(xiàn)雖然拋出了異常,但是程序并沒有停止,還在繼續(xù)輸出,

即使在 while 條件判斷處添加 !Thread.currentThread().isInterrupted() 條件,依然不能停止程序!

原因是

java語言在設(shè)計(jì) sleep() 函數(shù)時(shí),有這樣一個(gè)理念:

就是當(dāng)它一旦響應(yīng)中斷,便會(huì)把 interrupt 標(biāo)記位清除。

也就是說,雖然線程在 sleep 過程中收到了 interrupt 中斷通知,并且也捕獲到了異常、打印了異常信息,

但是由于 sleep 設(shè)計(jì)理念,導(dǎo)致 Thread.currentThread().isInterrupted() 標(biāo)記位會(huì)被清除,

所以才會(huì)導(dǎo)致程序不能退出。

這里如果要停止線程,只需要在 catch 內(nèi) 再調(diào)用一次 interrupt(); 方法

try {
    // 每次循環(huán)都要等待10毫秒,模擬阻塞
    Thread.sleep(10);
} catch (InterruptedException e) {
    e.printStackTrace();
    Thread.currentThread().interrupt();
}

所以說,不要以為調(diào)用了 interrupt() 方法,線程就一定會(huì)停止。

兩種停止線程最佳方法

1. 捕獲了 InterruptedException 之后的優(yōu)先選擇:在方法簽名中拋出異常

public class RightWayStopThreadInProd implements Runnable {

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadInProd());
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
    @Override
    public void run() {
        while (true) {
            System.out.println("go...");
            try {
                throwInMethod();
            } catch (InterruptedException e) {
                // 捕獲異常,進(jìn)行保存日志、停止程序等操作
                System.out.println("stop");
                e.printStackTrace();
            }
        }
    }
    /**
     * 如果方法內(nèi)要拋出異常,最好是將異常拋出去,由頂層的調(diào)用方去處理,而不是try/catch
     * 這樣調(diào)用方才能捕獲異常并作出其它操作
     * @throws InterruptedException
     */
    private void throwInMethod() throws InterruptedException {
        Thread.sleep(2000);
    }
}

如果方法內(nèi)要拋出異常,最好是將異常拋出去,由頂層的調(diào)用方去處理,而不是 try/catch

這樣調(diào)用方才能捕獲異常并做出其它操作。

2. 在 catch 中調(diào)用 Thread.currentThread().interrupt(); 來恢復(fù)設(shè)置中斷狀態(tài)

public class RightWayStopThreadInProd2 implements Runnable {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new RightWayStopThreadInProd2());
        thread.start();
        Thread.sleep(1000);
        thread.interrupt();
    }
    @Override
    public void run() {
        while (true) {
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("程序運(yùn)行結(jié)束");
                break;
            }
            reInterrupt();
        }
    }
    private void reInterrupt() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            e.printStackTrace();
        }
    }
}

這里的 if (Thread.currentThread().isInterrupted()) 判斷,就是要你的代碼有響應(yīng)中斷的能力。

總結(jié)

  • 調(diào)用 interrupt 方法不一定會(huì)中斷線程
  • 通知線程停止,線程不會(huì)立即停止,而是會(huì)在合適的時(shí)候停止
  • 代碼要有響應(yīng)中斷的能力

到此這篇關(guān)于java中使用interrupt通知線程停止詳析的文章就介紹到這了,更多相關(guān)java interrupt 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java異常架構(gòu)和異常關(guān)鍵字圖文詳解

    Java異常架構(gòu)和異常關(guān)鍵字圖文詳解

    Java異常是Java提供的一種識(shí)別及響應(yīng)錯(cuò)誤的一致性機(jī)制,下面這篇文章主要給大家介紹了關(guān)于Java異常架構(gòu)和異常關(guān)鍵字的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • spring是如何實(shí)現(xiàn)聲明式事務(wù)的

    spring是如何實(shí)現(xiàn)聲明式事務(wù)的

    這篇文章主要介紹了spring是如何實(shí)現(xiàn)聲明式事務(wù)的,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • SpringBoot中的三種應(yīng)用事件處理機(jī)制詳解

    SpringBoot中的三種應(yīng)用事件處理機(jī)制詳解

    在項(xiàng)目開發(fā)中,組件間的松耦合設(shè)計(jì)至關(guān)重要,應(yīng)用事件處理機(jī)制作為觀察者模式的一種實(shí)現(xiàn),允許系統(tǒng)在保持模塊獨(dú)立性的同時(shí)實(shí)現(xiàn)組件間的通信,SpringBoot延續(xù)并增強(qiáng)了Spring框架的事件機(jī)制,提供了多種靈活的事件處理方式,本文給大家介紹了SpringBoot中的三種應(yīng)用事件處理機(jī)制
    2025-04-04
  • java實(shí)現(xiàn)http的Post、Get、代理訪問請(qǐng)求

    java實(shí)現(xiàn)http的Post、Get、代理訪問請(qǐng)求

    這篇文章主要為大家提供了java實(shí)現(xiàn)http的Post、Get、代理訪問請(qǐng)求的相關(guān)代碼,感興趣的小伙伴們可以參考一下
    2016-01-01
  • SpringCloud鏈路追蹤組件Sleuth配置方法解析

    SpringCloud鏈路追蹤組件Sleuth配置方法解析

    這篇文章主要介紹了SpringCloud鏈路追蹤組件Sleuth配置方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Java多線程的實(shí)現(xiàn)方式詳解

    Java多線程的實(shí)現(xiàn)方式詳解

    這篇文章主要介紹了Java多線程的實(shí)現(xiàn)方式詳解,線程就是進(jìn)程中的單個(gè)順序控制流,也可以理解成是一條執(zhí)行路徑,java中之所以有多線程機(jī)制,目的就是為了提高程序的處理效率,需要的朋友可以參考下
    2023-08-08
  • Java中的取余與取模運(yùn)算概念、區(qū)別代碼實(shí)踐

    Java中的取余與取模運(yùn)算概念、區(qū)別代碼實(shí)踐

    這篇文章主要介紹了Java中的取余與取模運(yùn)算概念、區(qū)別代碼實(shí)踐,需要的朋友可以參考下
    2007-02-02
  • Spring注解實(shí)現(xiàn)自動(dòng)裝配過程解析

    Spring注解實(shí)現(xiàn)自動(dòng)裝配過程解析

    這篇文章主要介紹了Spring注解實(shí)現(xiàn)自動(dòng)裝配過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 一文帶你學(xué)會(huì)Java中ScheduledThreadPoolExecutor使用

    一文帶你學(xué)會(huì)Java中ScheduledThreadPoolExecutor使用

    ScheduledThreadPoolExecutor是Java并發(fā)包中的一個(gè)類,同時(shí)也是?ThreadPoolExecutor的一個(gè)子類,本文主要為大家介紹一下ScheduledThreadPoolExecutor使用,需要的可以參考下
    2024-12-12
  • Java枚舉類型enum的詳解及使用

    Java枚舉類型enum的詳解及使用

    這篇文章主要介紹了Java枚舉類型enum的詳解及使用的相關(guān)資料,需要的朋友可以參考下
    2017-05-05

最新評(píng)論

永康市| 家居| 兴隆县| 宜黄县| 大庆市| 吉木萨尔县| 太仆寺旗| 汶上县| 海南省| 赣州市| 博客| 云龙县| 乐山市| 遵义县| 东光县| 巫溪县| 西安市| 南陵县| 东乡族自治县| 关岭| 凌源市| 介休市| 会泽县| 萝北县| 禹城市| 天全县| 定边县| 尚志市| 玛沁县| 镶黄旗| 阳西县| 临沂市| 闽清县| 象州县| 大庆市| 拉萨市| 镶黄旗| 大竹县| 莱芜市| 皮山县| 大余县|