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

Java線程取消的三種方式

 更新時(shí)間:2024年12月18日 11:45:09   作者:louisgeek  
文章介紹了 Java 線程取消的 3 種方式,不推薦使用 stop 方法和 volatile 設(shè)標(biāo)記位停止線程,線程中斷機(jī)制是協(xié)作式的,一個(gè)線程請(qǐng)求中斷,另一線程響應(yīng),線程可檢查自身中斷狀態(tài)或捕獲 InterruptedException 來(lái)合適處理以響應(yīng)中斷,確保安全有序停止,避免資源泄露等問(wèn)題

Java 線程取消的 3 種方式

  • Thread 取消線程通常有以下幾種方式:
    • 1 使用 stop 方法來(lái)強(qiáng)制停止線程,是非常不安全的方式
    • 2 使用 volatile 設(shè)置標(biāo)記位停止線程,是一種不完全可靠的方式
    • 3 使用線程中斷機(jī)制以協(xié)作式的方式來(lái)停止線程
  • Thread#stop 停止線程,強(qiáng)制停止一個(gè)正在運(yùn)行的線程,該方法已廢棄
  • Thread#interrupt 中斷線程,請(qǐng)求線程中斷,將線程的中斷狀態(tài)設(shè)置為 true
  • Thread#isInterrupted 檢查線程的中斷狀態(tài),返回當(dāng)前線程的中斷狀態(tài),不會(huì)改變線程的中斷狀態(tài)
  • Thread#interrupted 檢查并清除線程的中斷狀態(tài),返回當(dāng)前線程的中斷狀態(tài),并將線程的中斷狀態(tài)重置為 false,不過(guò)需要注意的是這是一個(gè)靜態(tài)方法

強(qiáng)制停止線程

  • 不推薦使用 Thread#stop 來(lái)粗暴的停止線程,可能會(huì)引起以下問(wèn)題:
    • 1 Thread#stop 會(huì)立刻停止 run 方法中剩余的工作,包括在 catch 或 finally 等中的邏輯,因此可能會(huì)導(dǎo)致一些清理性的工作的得不到完成,比如文件,數(shù)據(jù)庫(kù)等的關(guān)閉操作,可能會(huì)導(dǎo)致資源泄露的問(wèn)題
    • 2 Thread#stop 會(huì)立即釋放該線程所持有的鎖,可能會(huì)導(dǎo)致數(shù)據(jù)得不到同步,出現(xiàn)數(shù)據(jù)不一致,也可能導(dǎo)致正在更新的數(shù)據(jù)結(jié)構(gòu)被損壞等問(wèn)題

設(shè)置 volatile 標(biāo)記位來(lái)停止線程

  • 使用 volatile 關(guān)鍵字來(lái)設(shè)置標(biāo)記位來(lái)停止線程在某些情況下是不完全可靠的:
    • 1 單純使用 volatile 關(guān)鍵字雖然可以保證變量的可見(jiàn)性(即一個(gè)線程對(duì)變量的修改能夠及時(shí)讓其他線程看到),但不能保證復(fù)合操作的原子性,可能會(huì)導(dǎo)致線程在不正確的時(shí)間點(diǎn)結(jié)束,導(dǎo)致出現(xiàn)不可預(yù)期的行為
    • 2 如果線程當(dāng)前正在阻塞或等待情況下,那么它將不會(huì)立刻響應(yīng)標(biāo)記位的變化,而是必須等到它從阻塞或等待狀態(tài)恢復(fù)過(guò)來(lái)才有機(jī)會(huì)去檢查標(biāo)記位,然后才能開(kāi)始處理結(jié)束流程,時(shí)間點(diǎn)可能就出現(xiàn)一定的滯后了

協(xié)作式中斷線程

  • 線程中斷機(jī)制是一種協(xié)作式機(jī)制,允許一個(gè)線程請(qǐng)求另一個(gè)線程應(yīng)該停止其正在執(zhí)行的操作,調(diào)用線程 Thread#interrupt 中斷操作并不會(huì)直接中斷線程(不會(huì)立即停止線程),而只是改變了目標(biāo)線程的中斷狀態(tài)這個(gè)標(biāo)志位,被請(qǐng)求中斷的線程可以在適當(dāng)位置(如循環(huán)條件、方法調(diào)用前后等)通過(guò)檢查自身的中斷狀態(tài)來(lái)判斷是否被中斷了,從而采取相應(yīng)的行動(dòng)去響應(yīng)這個(gè)中斷請(qǐng)求,不過(guò)甚至也可以選擇忽略它(因?yàn)轫憫?yīng)中斷并不是強(qiáng)制性的要求,這取決于具體的實(shí)現(xiàn)和需求)
  • 通常情況下線程檢查自身發(fā)現(xiàn)中斷狀態(tài)為 true 時(shí),表示該線程已經(jīng)被中斷,此時(shí)要盡快處理中斷請(qǐng)求,可以選擇去執(zhí)行一些清理資源、保存數(shù)據(jù)等操作,然后再結(jié)束線程
  • 這種設(shè)計(jì)使得線程中斷變得相對(duì)安全,因?yàn)榫€程仍有機(jī)會(huì)在合適的時(shí)地方用合理的方式結(jié)束自身的工作,而不是像 Thread#stop 那么被強(qiáng)制停止

線程任務(wù)執(zhí)行完后正常結(jié)束

public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            //模擬線程執(zhí)行任務(wù)
            for (int i = 0; i < 100000; i++) {
               System.out.println("線程運(yùn)行中 i=" + i);
            }
            //在執(zhí)行完所有任務(wù)后線程正常結(jié)束
            System.out.println("---- 線程結(jié)束 ----");
        }
    };
    thread.start();
}

加入請(qǐng)求線程中斷的邏輯

public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            //模擬線程執(zhí)行任務(wù)
            for (int i = 0; i < 100000; i++) {
               System.out.println("線程運(yùn)行中 i=" + i);
            }
            //雖然調(diào)用了 Thread#interrupt 方法請(qǐng)求線程中斷但還是會(huì)執(zhí)行完所有的任務(wù)
            System.out.println("---- 線程結(jié)束 ----");
        }
    };
    thread.start();
    //演示邏輯
    try {
        //等待一段時(shí)間后去中斷 thread 線程
        Thread.sleep(10);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("請(qǐng)求線程中斷");
    //對(duì) thread 線程請(qǐng)求線程中斷
    thread.interrupt();
}

說(shuō)明僅僅只改變中斷狀態(tài)是達(dá)不到取消線程的效果,需要繼續(xù)加入響應(yīng)中斷的邏輯

public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            //模擬線程執(zhí)行任務(wù)
            for (int i = 0; i < 100000; i++) {
                //目的就是讓線程在適當(dāng)?shù)臅r(shí)候檢查自身的中斷狀態(tài),并完成響應(yīng)中斷請(qǐng)求的邏輯
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("線程檢測(cè)到自身的中斷狀態(tài)為 true ,于是準(zhǔn)備停止");
                    //釋放資源并結(jié)束線程
                    break; //這里用 return 也行
                }
                System.out.println("線程運(yùn)行中 i=" + i);
            }
            //
            System.out.println("---- 線程結(jié)束 ----");
        }
    };
    thread.start();
    //演示邏輯
    try {
        //等待一段時(shí)間后去中斷 thread 線程
        Thread.sleep(10);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("請(qǐng)求線程中斷");
    //對(duì) thread 線程請(qǐng)求線程中斷
    thread.interrupt();
}

存在阻塞狀態(tài)(比如 Object#wait、Thread#sleep、Thread#join 或 Condition#await 等方法調(diào)用產(chǎn)生的)下的響應(yīng)中斷

public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            //模擬線程執(zhí)行任務(wù)
            for (int i = 0; i < 100000; i++) {
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    //當(dāng)一個(gè)線程在阻塞狀態(tài)時(shí)如果調(diào)用了該線程的 interrupt 方法的話,那么阻塞方法就會(huì)拋出 InterruptedException 異常,類似于線程檢測(cè)到自身的中斷狀態(tài)為 true,也就意味著這里需要加入響應(yīng)中斷的邏輯了
                    //這里拋出 InterruptedException 異常的設(shè)計(jì)是為了線程可以從阻塞狀態(tài)恢復(fù)(喚醒)過(guò)來(lái)(表示阻塞操作由于中斷而提前結(jié)束),能在線程結(jié)束前有機(jī)會(huì)去處理中斷請(qǐng)求
                    //另外拋出 InterruptedException 異常的同時(shí)會(huì)清除線程的中斷標(biāo)志位(中斷狀態(tài)被重置為 false)
                    //所以這里可以做一些停止線程任務(wù)繼續(xù)執(zhí)行的邏輯(比如直接退出循環(huán))或者也可以在這里再次調(diào)用 Thread#interrupt 重設(shè)中斷狀態(tài)(標(biāo)記回中斷狀態(tài)為 true)然后和適當(dāng)位置的 Thread#isInterrupted() 判斷配合來(lái)完成響應(yīng)中斷請(qǐng)求的邏輯
                    break;
                }
                System.out.println("線程運(yùn)行中 i=" + i);
            }
            //
            System.out.println("---- 線程結(jié)束 ----");
        }
    };
    thread.start();
    //演示邏輯
    try {
        //等待一段時(shí)間后去中斷 thread 線程
        Thread.sleep(10);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("請(qǐng)求線程中斷");
    //對(duì) thread 線程請(qǐng)求線程中斷
    thread.interrupt();
}

線程在阻塞狀態(tài)下也能正確響應(yīng)中斷請(qǐng)求

public static void main(String[] args) {
    Thread thread = new Thread() {
        @Override
        public void run() {
            //模擬線程執(zhí)行任務(wù)
            for (int i = 0; i < 100000; i++) {
                //適當(dāng)位置檢查自身的中斷狀態(tài),并完成響應(yīng)中斷請(qǐng)求的邏輯
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("線程檢測(cè)到自身的中斷狀態(tài)為 true ,于是準(zhǔn)備停止");
                    //釋放資源并結(jié)束線程
                    break; //這里用 return 也行
                }
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    //拋出 InterruptedException 異常的同時(shí)會(huì)清除中斷標(biāo)志位(中斷狀態(tài)被重置為 false)
                    //所以這里要特別注意,可以按需重設(shè)中斷標(biāo)志位,就能做到即使線程在阻塞狀態(tài)下也能夠正確地響應(yīng)中斷請(qǐng)求了(不然很容易錯(cuò)過(guò)外部設(shè)置的那一次中斷請(qǐng)求)
                    Thread.currentThread().interrupt();
                }
                System.out.println("線程運(yùn)行中 i=" + i);
            }
            //
            System.out.println("---- 線程結(jié)束 ----");
        }
    };
    thread.start();
    //演示邏輯
    try {
        //等待一段時(shí)間后去中斷 thread 線程
        Thread.sleep(10);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("請(qǐng)求線程中斷");
    //對(duì) thread 線程請(qǐng)求線程中斷
    thread.interrupt();
}

總結(jié)

  • 不推薦使用 stop 方法來(lái)強(qiáng)制停止線程,也不推薦使用 volatile 設(shè)置標(biāo)記位停止線程
  • 線程中斷機(jī)制是一種交互式取消方式,一個(gè)線程請(qǐng)求另一個(gè)線程中斷,而另一個(gè)線程就是對(duì)這個(gè)線程的請(qǐng)求中斷做出響應(yīng)(一個(gè)線程不應(yīng)該由其他線程來(lái)直接強(qiáng)制中斷或者停止,而是應(yīng)該由線程自己自行進(jìn)行停止,因?yàn)槿蝿?wù)本身的代碼肯定比發(fā)出取消請(qǐng)求的代碼更清楚了解自身該如何執(zhí)行清除釋放結(jié)束等工作,說(shuō)到底目標(biāo)線程比調(diào)用者更加了解自身線程應(yīng)不應(yīng)該被停止,何時(shí)停止,如何停止)
  • 線程自己檢查自身中斷狀態(tài)或者捕獲 InterruptedException 然后進(jìn)行合適的處理以響應(yīng)中斷
  • 通過(guò)合理地運(yùn)用線程中斷機(jī)制,可以確保線程能夠安全、有序地停止,從而避免資源泄露以及一些潛在的問(wèn)題

以上就是Java線程取消的三種方式的詳細(xì)內(nèi)容,更多關(guān)于Java線程取消的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Maven中的庫(kù)repository詳解

    Maven中的庫(kù)repository詳解

    Maven中要配置庫(kù),可以有多種方式,最直接的是在項(xiàng)目中的pom.xml文件中,通過(guò)<repositories>配置庫(kù),這樣配置的庫(kù)僅適用于當(dāng)前項(xiàng)目,這篇文章主要介紹了Maven中的庫(kù)(repository),需要的朋友可以參考下
    2024-01-01
  • servlet Cookie使用方法詳解(六)

    servlet Cookie使用方法詳解(六)

    這篇文章主要為大家詳細(xì)介紹了servlet Cookie的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • 在springboot項(xiàng)目中同時(shí)接收文件和多個(gè)參數(shù)的方法總結(jié)

    在springboot項(xiàng)目中同時(shí)接收文件和多個(gè)參數(shù)的方法總結(jié)

    在開(kāi)發(fā)接口中,遇到了需要同時(shí)接收文件和多個(gè)參數(shù)的情況,可以有多種方式實(shí)現(xiàn)文件和參數(shù)的同時(shí)接收,文中給大家介紹了兩種實(shí)現(xiàn)方法,感興趣的同學(xué)跟著小編一起來(lái)看看吧
    2023-08-08
  • Java基于Google zxing生成帶logo的二維碼圖片

    Java基于Google zxing生成帶logo的二維碼圖片

    zxing是一個(gè)開(kāi)放源碼的,用java實(shí)現(xiàn)的多種格式的1D/2D條碼圖像處理庫(kù),本文主要介紹了Java基于Google zxing生成帶logo的二維碼圖片,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • 模仿J2EE的session機(jī)制的App后端會(huì)話信息管理實(shí)例

    模仿J2EE的session機(jī)制的App后端會(huì)話信息管理實(shí)例

    下面小編就為大家分享一篇模仿J2EE的session機(jī)制的App后端會(huì)話信息管理實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • 分享一個(gè)簡(jiǎn)單的java爬蟲(chóng)框架

    分享一個(gè)簡(jiǎn)單的java爬蟲(chóng)框架

    這篇文章主要介紹了分享一個(gè)簡(jiǎn)單的java爬蟲(chóng)框架,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • java常用數(shù)據(jù)流應(yīng)用實(shí)例解析

    java常用數(shù)據(jù)流應(yīng)用實(shí)例解析

    這篇文章主要介紹了java常用數(shù)據(jù)流應(yīng)用實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 微信公眾號(hào)開(kāi)發(fā)之回復(fù)圖文消息java代碼

    微信公眾號(hào)開(kāi)發(fā)之回復(fù)圖文消息java代碼

    這篇文章主要為大家詳細(xì)介紹了微信公眾號(hào)開(kāi)發(fā)之回復(fù)圖文消息java代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • jxl操作excel寫(xiě)入數(shù)據(jù)不覆蓋原有數(shù)據(jù)示例

    jxl操作excel寫(xiě)入數(shù)據(jù)不覆蓋原有數(shù)據(jù)示例

    網(wǎng)上很多例子,都是用Jxl讀或者寫(xiě)excel,本文實(shí)現(xiàn)的功能就是將數(shù)據(jù)源in.xls的第幾行第幾列數(shù)據(jù)寫(xiě)入到out.xls的第幾行第幾列,不覆蓋out.xls其他原有的數(shù)據(jù)。
    2014-03-03
  • SpringBoot實(shí)現(xiàn)垂直分片的六種策略

    SpringBoot實(shí)現(xiàn)垂直分片的六種策略

    隨著業(yè)務(wù)規(guī)模的不斷擴(kuò)大,單一數(shù)據(jù)庫(kù)架構(gòu)往往難以滿足日益增長(zhǎng)的數(shù)據(jù)量和訪問(wèn)壓力,作為解決方案之一,垂直分片通過(guò)將不同業(yè)務(wù)模塊的數(shù)據(jù)分散到不同的數(shù)據(jù)庫(kù)或?qū)嵗?本文將介紹在SpringBoot環(huán)境下實(shí)現(xiàn)垂直分片的六種策略,需要的朋友可以參考下
    2025-06-06

最新評(píng)論

石首市| 常山县| 安丘市| 揭阳市| 紫阳县| 三明市| 临猗县| 兴隆县| 丰宁| 扶沟县| 牡丹江市| 项城市| 北辰区| 巫山县| 禄劝| 尤溪县| 嘉定区| 岑溪市| 岳普湖县| 灌阳县| 陇西县| 曲麻莱县| 清丰县| 丰都县| 吐鲁番市| 张掖市| 多伦县| 塘沽区| 鄂温| 公主岭市| 德庆县| 高安市| 榆树市| 长子县| 温宿县| 宁安市| 武定县| 淅川县| 渭源县| 旬邑县| 昌邑市|