欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java線程中斷機(jī)制interrupt、isInterrupted、interrupted方法詳解

 更新時間:2024年01月22日 09:01:48   作者:帥氣的喵喵  
這篇文章主要介紹了Java線程中斷機(jī)制interrupt、isInterrupted、interrupted方法詳解,一個線程不應(yīng)該由其他線程來強(qiáng)制中斷或停止,而是應(yīng)該由線程自己自行停止,所以,Thread.stop、Thread.suspend、Thread. resume都已經(jīng)被廢棄了,需要的朋友可以參考下

什么是中斷

  • 一個線程不應(yīng)該由其他線程來強(qiáng)制中斷或停止,而是應(yīng)該由線程自己自行停止,所以,Thread.stop、Thread.suspend、Thread. resume都已經(jīng)被廢棄了
  • 在Java中沒有辦法立即停止一條線程,然而停止線程卻顯得尤為重要,如取消一個耗時操作。因此,Java提供了一種用于停止線程的機(jī)制 — 中斷
  • 中斷只是一種協(xié)作機(jī)制,Java沒有給中斷增加任何語法,中斷的過程完全需要程序員自己實(shí)現(xiàn)
  • 若要中斷一個線程,你需要手動調(diào)用該線程的interrupt方法,該方法也僅僅是將線程對象的中斷標(biāo)識設(shè)為true
  • 每個線程對象中都有一個標(biāo)識,用于標(biāo)識線程是否被中斷;該標(biāo)識位為true表示中斷,為false表示未中斷,通過調(diào)用線程對象的interrupt方法將線程的標(biāo)識位設(shè)為true,可以在別的線程中調(diào)用,也可以在自己的線程中調(diào)用

源碼解讀(中斷的相關(guān)API)

void interrupt( )實(shí)例方法

 interrupt( )僅僅是設(shè)置線程的中斷狀態(tài)為true,不會停止線程

源碼解讀(如果這個線程因?yàn)閣ait()、join()、sleep()方法在用的過程中被打斷(interupt),會拋出Interrupte dException)

boolean isInterrupted( )實(shí)例方法

判斷當(dāng)前線程是否被中斷(通過檢查中斷標(biāo)識位) 實(shí)例方法

在這里插入圖片描述

static boolean interrupted( )靜態(tài)方法

 判斷線程是否被中斷,并清楚當(dāng)前中斷狀態(tài),這個方法做了兩件事 第一件事 返回當(dāng)前線程的中斷狀態(tài)

 第二件事 將當(dāng)前線程的中斷狀態(tài)設(shè)為false

原理:假設(shè)有兩個線程A、B,線程B調(diào)用了interrupt方法,這個時候我們連續(xù)調(diào)用兩次isInterrupted方法,第一次會返回true,然后這個方法會將中斷標(biāo)識位設(shè)置位false,所以第二次調(diào)用將返回false

在這里插入圖片描述

比較靜態(tài)方法interrupted和實(shí)例方法isInterrupted 靜態(tài)方法interrupted將會清除中斷狀態(tài)(傳入的參數(shù)ClearInterrupted位true)實(shí)例方法isInterrupted則不會(傳入的參數(shù)ClearInterrupted為false)

如何使用中斷標(biāo)識停止線程

在需要中斷的線程中不斷監(jiān)聽中斷狀態(tài),一旦發(fā)生中斷,就執(zhí)行型對于的中斷處理業(yè)務(wù)邏輯

三種中斷標(biāo)識停止線程的方式

  • 通過一個volatile變量實(shí)現(xiàn)
  • 通過AtomicBoolean
  • 通過Thread類自帶的中斷API方法實(shí)現(xiàn)
public class InterruptDemo{
    static volatile boolean isStop = false;
    static AtomicBoolean atomicBoolean = new AtomicBoolean(false);
    public static void m3(){
    Thread t1 = new Thread(() -> {
        while (true) {
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("-----isInterrupted() = true,程序結(jié)束。");
                break;
            }
            System.out.println("------hello Interrupt");
        }
    }, "t1");
    t1.start();
    try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
    new Thread(() -> {
        t1.interrupt();//修改t1線程的中斷標(biāo)志位為true
    },"t2").start();
}
    /**
     * 通過AtomicBoolean
     */
    public static void m2(){
        new Thread(() -> {
            while(true)
            {
                if(atomicBoolean.get())
                {
                    System.out.println("-----atomicBoolean.get() = true,程序結(jié)束。");
                    break;
                }
                System.out.println("------hello atomicBoolean");
            }
        },"t1").start();
        //暫停幾秒鐘線程
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        new Thread(() -> {
            atomicBoolean.set(true);
        },"t2").start();
    }
    /**
     * 通過一個volatile變量實(shí)現(xiàn)
     */
    public static void m1(){
        new Thread(() -> {
            while(true)
            {
                if(isStop)
                {
                    System.out.println("-----isStop = true,程序結(jié)束。");
                    break;
                }
                System.out.println("------hello isStop");
            }
        },"t1").start();
        //暫停幾秒鐘線程
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        new Thread(() -> {
            isStop = true;
        },"t2").start();
    }
}

當(dāng)前線程的中斷標(biāo)識為true,是不是就立刻停止?

1、線程調(diào)用interrupt()時①. 如果線程處于正常活動狀態(tài),那么會將線程的中斷標(biāo)志設(shè)置位true,僅此而已。被設(shè)置中斷標(biāo)志的線程將繼續(xù)正常運(yùn)行,不受影響。所以,interrupt( )并不能真正的中斷線程,需要被調(diào)用的線程自己進(jìn)行配合才行

如果線程處于被阻塞狀態(tài)(例如處于sleep、wait、join等狀態(tài)),在別的線程中調(diào)用當(dāng)前線程對象的interrupt方法,那么線程立即被阻塞狀態(tài),并拋出一個InterruptedException異常)

2、中斷只是一種協(xié)同機(jī)制,修改中斷標(biāo)識位僅此而已,不是立即stop打斷

3 、sleep、wait 等方法拋出InterruptedException后,中斷標(biāo)識也被清空置為false,我們在catch沒有通過調(diào)用th.interrupt( )方法再次將中斷標(biāo)識位設(shè)置位true,這就是導(dǎo)致無限循環(huán)了

總結(jié)

package com.bilibili.juc.interrupt;
import java.util.concurrent.TimeUnit;
/**
 * @auther zzyy
 * @create 2022-01-20 10:52
 */
public class InterruptDemo3
{
    public static void main(String[] args)
    {
        Thread t1 = new Thread(() -> {
            while (true)
            {
                if(Thread.currentThread().isInterrupted())
                {
                    System.out.println(Thread.currentThread().getName()+"\t " +
                            "中斷標(biāo)志位:"+Thread.currentThread().isInterrupted()+" 程序停止");
                    break;
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();//為什么要在異常處,再調(diào)用一次??
                    e.printStackTrace();
                }
                System.out.println("-----hello InterruptDemo3");
            }
        }, "t1");
        t1.start();
        //暫停幾秒鐘線程
        try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
        new Thread(() -> t1.interrupt(),"t2").start();
    }
}
/**
 * 1 中斷標(biāo)志位,默認(rèn)false
 * 2 t2 ----> t1發(fā)出了中斷協(xié)商,t2調(diào)用t1.interrupt(),中斷標(biāo)志位true
 * 3 中斷標(biāo)志位true,正常情況,程序停止,^_^
 * 4 中斷標(biāo)志位true,異常情況, 就是t1過程中調(diào)用了sleep 、join 、 wait 方法 會拋出一個 InterruptedException(中斷異常),
 * 將會把中斷狀態(tài)將被清除,并且將收到InterruptedException 。中斷標(biāo)志位重新設(shè)置為false 導(dǎo)致無限循環(huán)
 *
 * 5 所以如果要線程中調(diào)用sleep 、join 、 wait 方法 需要在catch塊中,需要再次給中斷標(biāo)志位設(shè)置為true,2次調(diào)用停止程序才OK
 */

到此這篇關(guān)于Java線程中斷機(jī)制interrupt、isInterrupted、interrupted方法詳解的文章就介紹到這了,更多相關(guān)Java線程中斷機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談一下數(shù)據(jù)庫連接池Druid德魯伊

    淺談一下數(shù)據(jù)庫連接池Druid德魯伊

    數(shù)據(jù)庫連接池就是一個容器持有多個數(shù)據(jù)庫連接,當(dāng)程序需要操作數(shù)據(jù)庫的時候直接從池中取出連接,使用完之后再還回去,和線程池一個道理,需要的朋友可以參考下
    2023-05-05
  • SpringBoot如何配置CROS Filter

    SpringBoot如何配置CROS Filter

    這篇文章主要介紹了SpringBoot如何配置CROS Filter問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • java線程池使用場景及一些建議

    java線程池使用場景及一些建議

    本文主要介紹了java線程池使用場景及一些建議,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Mybatis-Plus多種批量插入方案對比小結(jié)

    Mybatis-Plus多種批量插入方案對比小結(jié)

    在項(xiàng)目中優(yōu)化Mybatis-Plus批量插入性能是關(guān)鍵,通過比較不同方案,本文就來介紹一下Mybatis-Plus多種批量插入方案對比小結(jié),感興趣都的可以了解一下
    2024-10-10
  • Java RMI詳細(xì)介紹及簡單實(shí)例

    Java RMI詳細(xì)介紹及簡單實(shí)例

    這篇文章主要介紹了Java RMI詳細(xì)介紹及簡單實(shí)例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • java取兩個字符串的最大交集

    java取兩個字符串的最大交集

    這篇文章主要介紹了java取兩個字符串的最大交集的方法,涉及Java對字符串操作的技巧,具有一定的參考借鑒價值,需要的朋友可以參考下
    2014-10-10
  • 比較java中Future與FutureTask之間的關(guān)系

    比較java中Future與FutureTask之間的關(guān)系

    在本篇文章里我們給大家分享了java中Future與FutureTask之間的關(guān)系的內(nèi)容,有需要的朋友們可以跟著學(xué)習(xí)下。
    2018-10-10
  • 最全總結(jié)SpringBean的作用域管理

    最全總結(jié)SpringBean的作用域管理

    今天給大家詳細(xì)總結(jié)了SpringBean的作用域管理,文中有非常詳細(xì)的圖文介紹以及代碼示例,對正在學(xué)習(xí)java的小伙伴們還很有幫助,需要的朋友可以參考下
    2021-05-05
  • MyBatis-Plus 批量插入數(shù)據(jù)的操作方法

    MyBatis-Plus 批量插入數(shù)據(jù)的操作方法

    spring boot+mybatis plus環(huán)境,單條插入用的是BaseMapper自帶的insert方法,本文重點(diǎn)給大家介紹MyBatis-Plus 批量插入數(shù)據(jù)的操作方法,感興趣的朋友一起看看吧
    2021-09-09
  • Java運(yùn)行時動態(tài)生成類實(shí)現(xiàn)過程詳解

    Java運(yùn)行時動態(tài)生成類實(shí)現(xiàn)過程詳解

    這篇文章主要介紹了Java運(yùn)行時動態(tài)生成類實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07

最新評論