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

java 中斷線程的幾種方式 interrupt()詳解

 更新時間:2021年11月10日 09:18:58   作者:myseries  
中斷(Interrupt)一個線程意味著在該線程完成任務(wù)之前停止其正在進(jìn)行的一切,有效地中止其當(dāng)前的操作。這篇文章主要介紹了java 中斷線程的幾種方式 interrupt(),需要的朋友可以參考下

中斷

  中斷(Interrupt)一個線程意味著在該線程完成任務(wù)之前停止其正在進(jìn)行的一切,有效地中止其當(dāng)前的操作。線程是死亡、還是等待新的任務(wù)或是繼續(xù)運行至下一步,就取決于這個程序。雖然初次看來它可能顯得簡單,但是,你必須進(jìn)行一些預(yù)警以實現(xiàn)期望的結(jié)果。你最好還是牢記以下的幾點告誡。

  首先,忘掉Thread.stop方法。雖然它確實停止了一個正在運行的線程,然而,這種方法是不安全也是不受提倡的,這意味著,在未來的JAVA版本中,它將不復(fù)存在。

如何安全的結(jié)束一個正在運行的線程

 Thread類相關(guān)的方法

  java.lang.Thread類包含了一些常用的方法,如:start(), stop(), stop(Throwable) ,suspend(), destroy() ,resume()。通過這些方法,我們可以對線程進(jìn)行方便的操作,但是這些方法中,只有start()方法得到了保留。

  在JDK幫助文檔以及Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?》中都講解了舍棄這些方法的原因。

  簡單來說是因為:使用stop方法雖然可以強行終止正在運行或掛起的線程,但使用stop方法是很危險的,就象突然關(guān)閉計算機電源,而不是按正常程序關(guān)機一樣,可能會產(chǎn)生不可預(yù)料的結(jié)果,因此,并不推薦使用stop方法來終止線程。

 那么,我們究竟應(yīng)該如何停止線程呢?

1、任務(wù)中一般都會有循環(huán)結(jié)構(gòu),只要用一個標(biāo)記控制住循環(huán),就可以結(jié)束任務(wù)。

2、如果線程處于了凍結(jié)狀態(tài),無法讀取標(biāo)記,此時可以使用interrupt()方法將線程從凍結(jié)狀態(tài)強制恢復(fù)到運行狀態(tài)中來,讓線程具備CPU的執(zhí)行資格。

(一):使用退出標(biāo)志

  當(dāng)run方法執(zhí)行完后,線程就會退出。但有時run方法是永遠(yuǎn)不會結(jié)束的,如在服務(wù)端程序中使用線程進(jìn)行監(jiān)聽客戶端請求,或是其他的需要循環(huán)處理的任務(wù)。

  在這種情況下,一般是將這些任務(wù)放在一個循環(huán)中,如while循環(huán)。如果想使while循環(huán)在某一特定條件下退出,最直接的方法就是設(shè)一個boolean類型的標(biāo)志,并通過設(shè)置這個標(biāo)志為true或false來控制while循環(huán)是否退出。

public class test1 {

    public static volatile boolean exit =false;  //退出標(biāo)志
    
    public static void main(String[] args) {
        new Thread() {
            public void run() {
                System.out.println("線程啟動了");
                while (!exit) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("線程結(jié)束了");
            }
        }.start();
        
        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        exit = true;//5秒后更改退出標(biāo)志的值,沒有這段代碼,線程就一直不能停止
    }
}

(二):使用 interrupt 方法

  Thread.interrupt()方法: 作用是中斷線程。將會設(shè)置該線程的中斷狀態(tài)位,即設(shè)置為true,中斷的結(jié)果線程是死亡、還是等待新的任務(wù)或是繼續(xù)運行至下一步,就取決于這個程序本身。線程會不時地檢測這個中斷標(biāo)示位,以判斷線程是否應(yīng)該被中斷(中斷標(biāo)示值是否為true)。它并不像stop方法那樣會中斷一個正在運行的線程 

  interrupt()方法只是改變中斷狀態(tài),不會中斷一個正在運行的線程。需要用戶自己去監(jiān)視線程的狀態(tài)為并做處理。支持線程中斷的方法(也就是線程中斷后會拋出interruptedException的方法)就是在監(jiān)視線程的中斷狀態(tài),一旦線程的中斷狀態(tài)被置為“中斷狀態(tài)”,就會拋出中斷異常。這一方法實際完成的是,給受阻塞的線程發(fā)出一個中斷信號,這樣受阻線程檢查到中斷標(biāo)識,就得以退出阻塞的狀態(tài)。

更確切的說,如果線程被Object.wait, Thread.join和Thread.sleep三種方法之一阻塞,此時調(diào)用該線程的interrupt()方法,那么該線程將拋出一個 InterruptedException中斷異常(該線程必須事先預(yù)備好處理此異常),從而提早地終結(jié)被阻塞狀態(tài)。如果線程沒有被阻塞,這時調(diào)用 interrupt()將不起作用,直到執(zhí)行到wait(),sleep(),join()時,才馬上會拋出 InterruptedException。

 使用 interrupt() + InterruptedException來中斷線程

  線程處于阻塞狀態(tài),如Thread.sleep、wait、IO阻塞等情況時,調(diào)用interrupt方法后,sleep等方法將會拋出一個InterruptedException:

public static void main(String[] args) {
        Thread thread = new Thread() {
            public void run() {
                System.out.println("線程啟動了");
                try {
                    Thread.sleep(1000 * 100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("線程結(jié)束了");
            }
        };
        thread.start();

        try {
            Thread.sleep(1000 * 5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();//作用是:在線程阻塞時拋出一個中斷信號,這樣線程就得以退出阻塞的狀態(tài)
    }

 使用 interrupt() + isInterrupted()來中斷線程  

  this.interrupted():測試當(dāng)前線程是否已經(jīng)中斷(靜態(tài)方法)。如果連續(xù)調(diào)用該方法,則第二次調(diào)用將返回false。在api文檔中說明interrupted()方法具有清除狀態(tài)的功能。執(zhí)行后具有將狀態(tài)標(biāo)識清除為false的功能。

  this.isInterrupted():測試線程是否已經(jīng)中斷,但是不能清除狀態(tài)標(biāo)識。

public static void main(String[] args) {
        Thread thread = new Thread() {
            public void run() {
                System.out.println("線程啟動了");
                while (!isInterrupted()) {
                    System.out.println(isInterrupted());//調(diào)用 interrupt 之后為true
                }
                System.out.println("線程結(jié)束了");
            }
        };
        thread.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();
        System.out.println("線程是否被中斷:" + thread.isInterrupted());//true
    }

。。。。。。。。。。

來一個綜合的例子:

public class test1 {

    static volatile boolean flag = true;

    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("開始休眠");
                try {
                    Thread.sleep(100 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("結(jié)束休眠,開始死循環(huán)");
                while (flag) {
                }
                System.out.println("------------------子線程結(jié)束------------------");
            }
        });
        thread.start();

        Scanner scanner = new Scanner(System.in);
        System.out.println("輸入1拋出一個中斷異常,輸入2修改循環(huán)標(biāo)志位,輸入3判斷線程是否阻塞,輸入其他結(jié)束Scanner\n");
        while (scanner.hasNext()) {
            String text = scanner.next();
            System.out.println("你輸入了:" + text + "\n");
            if ("1".equals(text)) {
                thread.interrupt();
            } else if ("2".equals(text)) {
                flag = false; //如果不設(shè)為false,主線程結(jié)束后子線程仍在運行
            } else if ("3".equals(text)) {
                System.out.println(thread.isInterrupted());
            } else {
                scanner.close();
                break;
            }
        }
        System.out.println("------------------主線程結(jié)束------------------");
    }
}

不能結(jié)束的情況

注意下面這種是根本不能結(jié)束的情況!

public class Test {
    public static void main(String[] args) {
        Thread thread = new Thread() {
            public void run() {
                System.out.println("線程啟動了");
                while (true) {//對于這種情況,即使線程調(diào)用了intentrupt()方法并且isInterrupted(),但線程還是會繼續(xù)運行,根本停不下來!
                    System.out.println(isInterrupted());//調(diào)用interrupt之后為true
                }
            }
        };
        thread.start();
        thread.interrupt();//注意,此方法不會中斷一個正在運行的線程,它的作用是:在線程受到阻塞時拋出一個中斷信號,這樣線程就得以退出阻塞的狀態(tài)
        while (true) {
            System.out.println("是否isInterrupted:" + thread.isInterrupted());//true
        }
    }
}

關(guān)于interrupted()和isInterrupted()方法的注意事項說明

  interrupted()是靜態(tài)方法:內(nèi)部實現(xiàn)是調(diào)用的當(dāng)前線程的isInterrupted(),并且會重置當(dāng)前線程的中斷狀態(tài)。

    測試當(dāng)前線程是否已經(jīng)中斷(靜態(tài)方法)。返回的是上一次的中斷狀態(tài),并且會清除該狀態(tài),所以連續(xù)調(diào)用兩次,第一次返回true,第二次返回false。

  isInterrupted()是實例方法,是調(diào)用該方法的對象所表示的那個線程的isInterrupted(),不會重置當(dāng)前線程的中斷狀態(tài)

    測試線程當(dāng)前是否已經(jīng)中斷,但是不能清除狀態(tài)標(biāo)識。

測試方法驗證:

1:

  第一個紅框中斷的線程是我們自己創(chuàng)建的thread線程,我調(diào)用的interrupted(),由上面源碼可知是判斷當(dāng)前線程的中斷狀態(tài),當(dāng)前線程是main線程,我根本沒有中斷過main線程,所以2次調(diào)用均返回“false”

2:

  第一個紅框中斷的線程是當(dāng)前線程(main線程),我調(diào)用的interrupted(),由上面源碼可知是判斷當(dāng)前線程的中斷狀態(tài),當(dāng)前線程是main線程,所以第1次調(diào)用結(jié)果返回“true”,因為我確實中斷了main線程

  由源碼可知interrupted()調(diào)用的是isInterrupted(),并會重置中斷狀態(tài),所以第一次調(diào)用之后把中斷狀態(tài)給重置了,從中斷狀態(tài)重置為非中斷狀態(tài),所以第2次調(diào)用的結(jié)果返回“false”

3:

  第一個紅框中斷的線程是我們自己創(chuàng)建的thread線程,我調(diào)用的isInterrupted(),由上面源碼可知是判斷執(zhí)行該方法的對象所表示線程的中斷狀態(tài),也就是thread引用所表示的線程的中斷狀態(tài),所以第1次調(diào)用結(jié)果返回“true”,

  由源碼可知isInterrupted()不會重置中斷狀態(tài),所以第一次調(diào)用之后沒有把中斷狀態(tài)給重置(從中斷狀態(tài)重置為非中斷狀態(tài)),所以第2次調(diào)用的結(jié)果還返回“true”

到此這篇關(guān)于java 中斷線程的幾種方式 interrupt()的文章就介紹到這了,更多相關(guān)java 中斷線程interrupt()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 利用Mybatis?Plus實現(xiàn)一個SQL攔截器

    利用Mybatis?Plus實現(xiàn)一個SQL攔截器

    SQL攔截器是一種用于攔截和修改Mybatis執(zhí)行的SQL語句的工具,通過使用SQL攔截器,開發(fā)人員可以在執(zhí)行SQL語句之前或之后對其進(jìn)行修改或記錄,本文就來借助一下Mybatis-Plus實現(xiàn)一個SQL攔截器吧
    2023-05-05
  • SpringBoot中EasyExcel實現(xiàn)execl導(dǎo)入導(dǎo)出

    SpringBoot中EasyExcel實現(xiàn)execl導(dǎo)入導(dǎo)出

    本文主要介紹了SpringBoot中EasyExcel實現(xiàn)execl導(dǎo)入導(dǎo)出,實現(xiàn)了如何準(zhǔn)備環(huán)境、創(chuàng)建實體類、自定義轉(zhuǎn)換器以及編寫導(dǎo)入邏輯的步驟和示例代碼,感興趣的可以了解下
    2023-06-06
  • Mybatis如何按順序查詢出對應(yīng)的數(shù)據(jù)字段

    Mybatis如何按順序查詢出對應(yīng)的數(shù)據(jù)字段

    這篇文章主要介紹了Mybatis如何按順序查詢出對應(yīng)的數(shù)據(jù)字段,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • springboot集成nacos讀取nacos配置數(shù)據(jù)的原理

    springboot集成nacos讀取nacos配置數(shù)據(jù)的原理

    這篇文章主要介紹了springboot集成nacos讀取nacos配置數(shù)據(jù)的原理,文中有詳細(xì)的代碼流程,對大家學(xué)習(xí)springboot集成nacos有一定的幫助,需要的朋友可以參考下
    2023-05-05
  • SpringBoot中@ConfigurationProperties注解實現(xiàn)配置綁定的三種方法

    SpringBoot中@ConfigurationProperties注解實現(xiàn)配置綁定的三種方法

    這篇文章主要介紹了SpringBoot中@ConfigurationProperties注解實現(xiàn)配置綁定的三種方法,文章內(nèi)容介紹詳細(xì)需要的小伙伴可以參考一下
    2022-04-04
  • 解決SpringBoot jar包中的文件讀取問題實現(xiàn)

    解決SpringBoot jar包中的文件讀取問題實現(xiàn)

    這篇文章主要介紹了解決SpringBoot jar包中的文件讀取問題實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • java 高并發(fā)中volatile的實現(xiàn)原理

    java 高并發(fā)中volatile的實現(xiàn)原理

    這篇文章主要介紹了java 高并發(fā)中volatile的實現(xiàn)原理的相關(guān)資料,在多線程并發(fā)編程中synchronized和Volatile都扮演著重要的角色,Volatile是輕量級的synchronized,它在多處理器開發(fā)中保證了共享變量的“可見性”,需要的朋友可以參考下
    2017-03-03
  • JAVA中值類型和引用類型的區(qū)別

    JAVA中值類型和引用類型的區(qū)別

    在java開發(fā)中經(jīng)常會遇到值類型和引用類型知識,但是有很多朋友不清楚java中值類型和引用類型的區(qū)別,今天小編通過本文給大家介紹下
    2017-02-02
  • java?Comparable和Comparator的區(qū)別及作用面試精講

    java?Comparable和Comparator的區(qū)別及作用面試精講

    這篇文章主要為大家介紹了java?Comparable和Comparator的區(qū)別及作用面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • spring+apollo動態(tài)獲取yaml格式的配置方式

    spring+apollo動態(tài)獲取yaml格式的配置方式

    這篇文章主要介紹了spring+apollo動態(tài)獲取yaml格式的配置方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04

最新評論

嘉兴市| 鹤壁市| 拉萨市| 绥棱县| 兴安县| 南康市| 济宁市| 肥东县| 邳州市| 卢湾区| 兖州市| 新乐市| 铜川市| 吉隆县| 延边| 大荔县| 卢氏县| 宜州市| 左云县| 长春市| 乐至县| 扶绥县| 白水县| 伊春市| 遵义县| 盐城市| 桑植县| 安宁市| 保定市| 沙河市| 阜平县| 额尔古纳市| 湖南省| 沁源县| 鄂伦春自治旗| 宽城| 民勤县| 曲沃县| 景宁| 措勤县| 大渡口区|