91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java多線程之Interrupt中斷線程的示例分析

發布時間:2021-05-20 09:35:31 來源:億速云 閱讀:207 作者:小新 欄目:開發技術

小編給大家分享一下Java多線程之Interrupt中斷線程的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

一、測試代碼

https://gitee.com/zture/spring-test/blob/master/multithreading/src/test/java/cn/diswares/blog/InterruptTests.java

二、測試

為了方便理解簡介中 interrupt 的概念, 寫個 DEMO 測試一下

 /**
 * 調用 interrupt 并不會影響線程正常運行
 */
@Test
public void testInvokeInterrupt() throws InterruptedException {
    Thread t1 = new Thread(() -> {
    for (int i = 0; ; i++) {
    log.info(i + "");
    }
    });
    t1.start();
    // 確保 t1.start() 成功執行
    Thread.sleep(1);
    log.info("interrupt 前 t1 interrupt 狀態 = {}", t1.isInterrupted());
    t1.interrupt();
    log.info("interrupt 后 t1 interrupt 狀態 = {}", t1.isInterrupted());
    log.info("t1 是否存活 = {}", t1.isAlive());
}

三、執行過程描述

  • 首先 main 線程中啟動 t1線程

  • t1 線程死循環輸出 i++

  • main 線程確保 t1.start() 執行后

  • 打印 t1 線程的線程中斷狀態

  • 調用 t1.interrupt() 方法使線程中斷

  • 打印 t1 線程的線程中斷狀態

四、輸出日志

ignore logs ......
20:29:57.632 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2561
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2562
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2563
20:29:57.486 [main] INFO cn.diswares.blog.interrupt.InterruptTests - interrupt 前 t1 interrupt 狀態 = false
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2564
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2565
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2566
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2567
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2568
20:29:57.633 [main] INFO cn.diswares.blog.interrupt.InterruptTests - interrupt 后 t1 interrupt 狀態 = true
20:29:57.633 [main] INFO cn.diswares.blog.interrupt.InterruptTests - t1 是否存活 = true
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2569
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2570
20:29:57.633 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - 2571
ignore logs ......

現象描述

  • 調用 t1.interrupt() 執行前線程的 interrupt 狀態為 false

  • 調用 t1.interrupt() 執行后線程的 interrupt 狀態為 true

  • 線程并沒有被中斷, 可以成功死循環輸出循環次數

五、結論

Interrupt 的真正作用是給線程對象設置一個中斷標記, 并不會影響線程的正常運行

六、主要方法釋義

new Thread().interrupt()

中斷此線程(此線程不一定是當前線程,而是指調用該方法的Thread實例所代表的線程),但實際上只是給線程設置一個中斷標志,線程仍會繼續運行。

Thread.interrupted()

注意: 這是個靜態方法
測試當前線程是否被中斷(檢查中斷標志), 返回一個當前線程的 interrupt 狀態, 并重置.
當我們第二次調用時中斷狀態已經被重置, 將返回一個false
為了方便理解. 寫一個 DEMO

七、DEMO

DEMO 非常簡單, 調用兩次 Thread.interrupted() 觀察 main 線程的 interrupt 標記

/**
 * 二次調用 t1.interrupted()
 */
@Test
public void testDoubleInvokeInterrupted () throws InterruptedException {
    Thread.currentThread().interrupt();
    log.info("interrupted1 = {}", Thread.interrupted());
    log.info("interrupted2 = {}", Thread.interrupted());
}

輸出日志

21:06:33.397 [main] INFO cn.diswares.blog.interrupt.InterruptTests - interrupted1 = true
21:06:33.402 [main] INFO cn.diswares.blog.interrupt.InterruptTests - interrupted2 = false

八、拓展程序

由于是靜態方法. 我們來看一下另一個小程序.

  • 跟之前一樣將 t1 程序中斷

  • 調用 t1.interrupted()

  • 注意這里是個靜態方法

/**
 * 在主線程中調用 t1.interrupted()
 */
@Test
public void testMainInterrupted() throws InterruptedException {
    Thread t1 = new Thread(() -> {
        for (int i = 0; ; i++) {
            log.info("t1 is live");
        }
    });

    t1.start();
    Thread.sleep(1);
    t1.interrupt();
    Thread.sleep(1);
    log.info("{}", t1.interrupted());
}

拓展程序日志

ignore logs ......
21:11:20.504 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - t1 is live
21:11:20.504 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - t1 is live
21:11:20.490 [main] INFO cn.diswares.blog.interrupt.InterruptTests - false
21:11:20.504 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - t1 is live
21:11:20.504 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - t1 is live
21:11:20.504 [Thread-1] INFO cn.diswares.blog.interrupt.InterruptTests - t1 is live
ignore logs ......

拓展程序結論

  • Thread.interrupted() 方法是靜態方法

  • 它的實現為 Thread.currentThread(), 獲取的是當前正在執行的線程, JDK 原文注釋如下

Returns a reference to the currently executing thread object.

Returns: the currently executing thread.

  • 所以這里 t1.interrupted() 返回的其實是 main 線程的線程中斷標記

new Thread().isInterrupted()

返回線程對象的中斷標記, 不會改變中斷標記

  • true: 中斷標記存在

  • false: 未設置中斷標記狀態

優雅的結束一個線程

在 Java 中結束一個線程一般有下面三種手段:

  • (禁用) Thread.stop() 這個方法已經被廢棄. 因為這種結束線程的方式過于暴力. 會將當前線程暴力終結. 同時線程持有的鎖也都會釋放, 并且用戶有任何額外的處理來控制, 會導致數據不一致

  • volatile: 外部申明 volatile 開關變量, 當開關條件不滿足時結束

  • (推薦) interrupt: 最優雅的方案

九、實戰

最初的 DEMO 是個死循環, 那我們對其改造一下. 讓它能夠優雅的結束

/**
 * 調用 interrupt 并不會影響線程正常運行
 */
@Test
public void testGracefulEndThread() throws InterruptedException {
    Thread t1 = new Thread(() -> {
        for (int i = 0; ; i++) {
            if (Thread.currentThread().isInterrupted()) {
                log.info("{} = true, i = {}", Thread.currentThread().getName(), i);
                break;
            } else {
                log.info("{} = false, i = {}", Thread.currentThread().getName(), i);
            }
        }
    });
    t1.start();
    // 確保 t1.start() 成功執行
    TimeUnit.SECONDS.sleep(1);
    t1.interrupt();
    TimeUnit.SECONDS.sleep(1);
    log.info(t1.getState().toString());
}

Java的優點是什么

1. 簡單,只需理解基本的概念,就可以編寫適合于各種情況的應用程序;2. 面向對象;3. 分布性,Java是面向網絡的語言;4. 魯棒性,java提供自動垃圾收集來進行內存管理,防止程序員在管理內存時容易產生的錯誤。;5. 安全性,用于網絡、分布環境下的Java必須防止病毒的入侵。6. 體系結構中立,只要安裝了Java運行時系統,就可在任意處理器上運行。7. 可移植性,Java可以方便地移植到網絡上的不同機器。8.解釋執行,Java解釋器直接對Java字節碼進行解釋執行。

看完了這篇文章,相信你對“Java多線程之Interrupt中斷線程的示例分析”有了一定的了解,如果想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绥棱县| 北安市| 阳高县| 慈溪市| 宿松县| 启东市| 林周县| 古丈县| 陵川县| 深圳市| 南召县| 加查县| 张家口市| 灵宝市| 葵青区| 潍坊市| 宜川县| 定西市| 灵石县| 沽源县| 延吉市| 贺州市| 吴旗县| 高阳县| 新巴尔虎左旗| 博白县| 上蔡县| 温州市| 岫岩| 巩留县| 桑植县| 吉安县| 石嘴山市| 永善县| 商都县| 连州市| 徐水县| 泰和县| 长阳| 闽清县| 昭平县|