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

詳解Java如何關閉線程以及線程池

 更新時間:2022年04月18日 10:22:31   作者:碼農(nóng)研究僧  
java如何正確關閉線程以及線程池是一個高頻的面試題,本文將為大家詳細介紹實現(xiàn)的方法與代碼,感興趣的小伙伴快跟隨小編一起學習一下

前言

這個問題是一個高頻的面試題

而且在印象中是由stop方法執(zhí)行或者終端中的kill殺死

但是這些方法直接簡單粗暴,很不安全,而且也不推廣

不使用stop的方法

之所以不安全不推廣是因為:

  • stop方法不管線程邏輯是否完整,都會終止當前正在運行的線程
  • 會破壞其原子邏輯(多線程加了鎖之解決資源共享,但是stop會將其所有鎖丟棄,造成混亂)

1. 關閉線程

1.1 volatile關鍵字

使用自定義的標志位決定線程的執(zhí)行情況

具體思路大致如下:設置一個 父線程 的狀態(tài)變量,以其影響其子線程即可

public class test extends Thread {
    //標識線程是否結束
    public static boolean thread_stop = true;

    public void stopThread() {
        thread_stop = false;
    }


    public static void main(String[] args) {
        test t = new test();
        t.start();
        System.out.println("Father Thread Start");
        try {
            //先讓線程跑起來
            Thread.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //結束線程

        //將其狀態(tài)變量直接改為false
        //thread_stop = false;

        //調用方法改為false(與狀態(tài)變量直接修改 一個道理)
        t.stopThread();

        System.out.println("Father Thread end");
    }


    @Override
    public void run() {
        while (thread_stop) {
            System.out.println("Child Thread Start");
        }
        System.out.println("Child Thread end");
    }
}

但是網(wǎng)上說不加volatile是停不下來的,其實是可以停下來的

只不過

加了volatile有幾個好處:

  • volatile可以保證狀態(tài)變量為系統(tǒng)內存值而不是緩存里值(避免值不一致)
  • volatile 關鍵字能夠是該變量對其他線程“可見”,即當主線程修改變量并刷新到主內存后,會讓其他線程去主內存中讀取該變量。當然,volatile并不能保證線程的安全性

具體加在狀態(tài)變量中的位置如下:

//標識線程是否結束
public static volatile boolean thread_stop = true;

之后具體完整的輸出為:

具體完整的輸出為:

Father Thread start
Child Thread Start
Child Thread Start
。。。
。。。
Child Thread Start
Child Thread Start
Father Thread end
Child Thread end

1.2 intrrrupt()方法

不能終止一個正在執(zhí)行著的線程,它只是修改中斷標志而已

這個方法分為兩種情況:

線程處于阻塞:立馬退出阻塞,拋出InterruptedException異常。通過捕獲這個異常,來讓線程退出

線程處于非阻塞:處于運行狀態(tài)不受影響,僅僅標記了線程的中斷為true。在適當?shù)奈恢弥姓{用isInterrupted方法查看是否被中斷并且退出

public class test extends Thread {
    public static void main(String[] args) {
        test t = new test();
        t.start();
        System.out.println("Father Thread Start");
        try {
            //先讓線程跑起來
            Thread.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //結束線程

        t.interrupt();

        System.out.println("Father Thread end");
    }


    @Override
    public void run() {
    //分配線程的中斷狀態(tài),并且此狀態(tài)可以由interrupted()方法生成
        while (!Thread.interrupted()) {
            System.out.println("Child Thread Start");
        }
        System.out.println("Child Thread end");
    }
}

執(zhí)行結果截圖:

具體完整的輸出為:

Father Thread start
Child Thread Start
Child Thread Start
。。。
。。。
Child Thread Start
Child Thread Start
Father Thread end
Child Thread end

2.關閉線程池

優(yōu)雅的關閉線程池:(比如ThreadPoolExecutor類)

可以通過shutdown方法逐步關閉池中的線程(溫和安全)

shutdown():拒收新任務,不會立即終止線程池。而是要等所有任務緩存隊列中的任務都執(zhí)行完后才終止。

shutdownNow():拒收新任務,立即終止線程池。并嘗試打斷正在執(zhí)行的任務。

并且清空任務緩存隊列,返回尚未執(zhí)行的任務

以下是對兩個線程池關閉的方法源代碼進行分析

而且關閉的途中,這兩個方法也不是瞬間立馬關閉,等待關閉的同時,還還調用awaitTermination方法來阻塞等待

2.1 shutdownNow()方法

查看java的源代碼

在try內部結構中

1.檢查其狀態(tài)

2.原子性的修改線程池的狀態(tài)為stop

3.遍歷工作隊列線程,調用interrupt方法

4.將隊列中還未執(zhí)行的放到任務隊列

源碼內部:其邏輯就是修改線程池狀態(tài)為stop,工作隊列中調用interrupt方法

在調用shutdownNow方法:

  • 正在執(zhí)行的線程會(getTask返回null)導致線程退出。
  • 隊列中讀取的任務會阻塞,拋出異常之后。工作隊列就會調用interrupt方法

2.2 shutdown()方法

同樣也是看java的源代碼

同樣也是4步狀態(tài)

1.檢查其狀態(tài)

2.修改線程池狀態(tài)為SHUTDOWN

3.調用interruptIdleWorkers方法中斷空閑線程(只有加鎖成功的線程才會被調用interrupt方法)

而正在執(zhí)行的線程是加鎖失敗,不會被中斷

主要通過這個函數(shù)去區(qū)分判斷

以上就是詳解Java如何關閉線程以及線程池的詳細內容,更多關于Java關閉線程 線程池的資料請關注腳本之家其它相關文章!

相關文章

  • springboot啟動不加載bootstrap.yml文件的問題

    springboot啟動不加載bootstrap.yml文件的問題

    這篇文章主要介紹了springboot啟動不加載bootstrap.yml文件的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java FileDescriptor總結_動力節(jié)點Java學院整理

    Java FileDescriptor總結_動力節(jié)點Java學院整理

    FileDescriptor 是“文件描述符”??梢员挥脕肀硎鹃_放文件、開放套接字等。接下來通過本文給大家分享Java FileDescriptor總結,感興趣的朋友一起學習吧
    2017-05-05
  • Java全面分析面向對象之繼承

    Java全面分析面向對象之繼承

    繼承就是可以直接使用前輩的屬性和方法。自然界如果沒有繼承,那一切都是處于混沌狀態(tài)。多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力。多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作
    2022-04-04
  • SpringMVC實現(xiàn)RESTful風格:@PathVariable注解的使用方式

    SpringMVC實現(xiàn)RESTful風格:@PathVariable注解的使用方式

    這篇文章主要介紹了SpringMVC實現(xiàn)RESTful風格:@PathVariable注解的使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java如何利用NIO壓縮文件或文件夾

    java如何利用NIO壓縮文件或文件夾

    這篇文章主要介紹了java如何利用NIO壓縮文件或文件夾問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 利用javaFX實現(xiàn)移動一個小球的示例代碼

    利用javaFX實現(xiàn)移動一個小球的示例代碼

    這篇文章主要介紹了利用javaFX實現(xiàn)移動一個小球的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • IDEA中編寫并運行shell腳本的實現(xiàn)

    IDEA中編寫并運行shell腳本的實現(xiàn)

    這篇文章主要介紹了IDEA中編寫并運行shell腳本的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • java中接口和事件監(jiān)聽器的深入理解

    java中接口和事件監(jiān)聽器的深入理解

    這篇文章主要給大家介紹了關于java中接口和事件監(jiān)聽器的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-12-12
  • Java使用jni清屏功能的實現(xiàn)(只針對cmd)

    Java使用jni清屏功能的實現(xiàn)(只針對cmd)

    JNI是Java Native Interface的縮寫,它提供了若干的API實現(xiàn)了Java和其他語言的通信(主要是C&C++)。這篇文章主要介紹了Java使用jni清屏功能的實現(xiàn)(只針對cmd) ,感興趣的朋友跟隨腳本之家小編一起學習吧
    2018-05-05
  • 詳解Spring?Bean的集合注入和自動裝配

    詳解Spring?Bean的集合注入和自動裝配

    這篇文章主要為大家詳細介紹了Spring?Bean中集合注入和自動裝配的方法,文中的示例代碼講解詳細,對我們學習有一定的幫助,需要的可以參考一下
    2022-06-06

最新評論