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

JVM鉤子函數(shù)的使用場(chǎng)景詳解

 更新時(shí)間:2021年08月22日 16:00:24   作者:Acelin_H  
當(dāng)jvm進(jìn)程退出的時(shí)候,或者受到了系統(tǒng)的中斷信號(hào),hook線程就會(huì)啟動(dòng),一個(gè)線程可以注入多個(gè)鉤,下面這篇文章主要給大家介紹了關(guān)于JVM鉤子函數(shù)使用的相關(guān)資料,需要的朋友可以參考下

一、問(wèn)題引入

背景

在編寫(xiě)一個(gè)需要持續(xù)在后臺(tái)運(yùn)行的程序的時(shí)候遇到了這樣的場(chǎng)景:我的程序在主函數(shù)中創(chuàng)建了一個(gè)線程池周期性地執(zhí)行任務(wù),我希望主線程和線程池都持續(xù)運(yùn)行,但如果收到外部的關(guān)閉信號(hào)時(shí),主線程和線程池也都能同時(shí)退出。想到的就是程序結(jié)束的時(shí)候需要有一個(gè)stop()方法去手動(dòng)關(guān)閉線程池,但是怎么控制這個(gè)stop()方法在我想要的時(shí)候調(diào)用,以什么形式去接收外部的關(guān)閉信號(hào)也成了需要考慮的問(wèn)題。

原始思路

最開(kāi)始的嘗試是我將程序的運(yùn)行和停止分別用"start"和"stop"兩種狀態(tài)表示,然后用一個(gè)狀態(tài)文件state去記錄當(dāng)前的狀態(tài)(程序啟動(dòng)時(shí)默認(rèn)是"start"),如果想要關(guān)閉這個(gè)正在運(yùn)行的程序,就去修改狀態(tài)文件state,將里面內(nèi)容變?yōu)?stop"。同時(shí)在主函數(shù)中打開(kāi)這個(gè)狀態(tài)文件,循環(huán)監(jiān)聽(tīng)里面的內(nèi)容,如果發(fā)現(xiàn)變?yōu)?stop",就去調(diào)用stop()方法執(zhí)行關(guān)閉邏輯。按照這個(gè)思路,我寫(xiě)了一個(gè)簡(jiǎn)單的程序在IDEA中測(cè)試了一下效果,發(fā)現(xiàn)是可行的。但是當(dāng)我將程序打包,在mac系統(tǒng)上運(yùn)行jar包進(jìn)行測(cè)試的時(shí)候,不知什么原因,程序總是讀到state文件剛打開(kāi)時(shí)的內(nèi)容,不能檢測(cè)到state文件的變化,無(wú)法按我設(shè)想的方式進(jìn)行關(guān)閉。因此只能另想辦法。

無(wú)意間看見(jiàn)JVM鉤子函數(shù)的介紹,發(fā)現(xiàn)這可能正是我想要的,于是趕緊拿來(lái)試一試。

二、JVM鉤子使用場(chǎng)景

JVM關(guān)閉的情況如下圖所示分為三類(lèi),第一種是正常的關(guān)閉,第二種是異常關(guān)閉的情況,第三種是強(qiáng)制關(guān)閉的情況。

JVM鉤子函數(shù)對(duì)于前兩種方式都可以進(jìn)行優(yōu)雅的關(guān)閉,但是對(duì)最后一種強(qiáng)制關(guān)閉就不起作用了。

下面我會(huì)根據(jù)這三種JVM關(guān)閉過(guò)程進(jìn)行簡(jiǎn)單演示。

正常關(guān)閉

代碼如下:

public class TestJVMHook {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(()->
                stop()
        ));
        start();
        System.out.println("===程序正常結(jié)束===");
    }
    public static void start() {
        System.out.println("===調(diào)用start()方法===");
    }

    public static void stop() {
        System.out.println("===調(diào)用stop()方法===");
    }
}

運(yùn)行結(jié)果:

===調(diào)用start()方法===
===程序正常結(jié)束===
===調(diào)用stop()方法===

可以看到,在鉤子函數(shù)中聲明了stop()方法,然后程序正常結(jié)束后會(huì)自動(dòng)調(diào)用鉤子函數(shù)。

異常關(guān)閉

異常關(guān)閉分為OOM和RuntimeException兩種情況,我用除數(shù)為0的運(yùn)行時(shí)異常來(lái)演示。

代碼如下:

public class TestJVMHook {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(()->
                stop()
        ));
        start();
        int res = 10/0;
        System.out.println("===程序結(jié)束===");
    }
    public static void start() {
        System.out.println("===調(diào)用start()方法===");
    }

    public static void stop() {
        System.out.println("===調(diào)用stop()方法===");
    }
}

運(yùn)行結(jié)果:

===調(diào)用start()方法===
===調(diào)用stop()方法===
Exception in thread "main" java.lang.ArithmeticException: / by zero
 at com.example.TestJVMHook.main(TestJVMHook.java:9)

可以看到執(zhí)行"10/0"時(shí)發(fā)生運(yùn)行時(shí)異常,并不會(huì)正常打印下一行語(yǔ)句,但仍然會(huì)自動(dòng)調(diào)用鉤子函數(shù)中stop()方法。

強(qiáng)制關(guān)閉

這里我們啟動(dòng)一個(gè)循環(huán)程序,然后手動(dòng)去關(guān)閉它。

代碼如下:

public class TestJVMHook {
    public static void main(String[] args) throws InterruptedException {
        Runtime.getRuntime().addShutdownHook(new Thread(()->
                stop()
        ));
        int count = 1;
        start();
        while(true){
            System.out.println("循環(huán)計(jì)數(shù)器"+(count++));
            Thread.sleep(5*1000);
        }
    }
    public static void start() {
        System.out.println("===調(diào)用start()方法===");
    }

    public static void stop() {
        System.out.println("===調(diào)用stop()方法===");
    }
}

啟動(dòng)后查看進(jìn)程id,然后通過(guò)"kill -9 <pid>"強(qiáng)制關(guān)閉:

運(yùn)行結(jié)果:

還是上面那段代碼,再次啟動(dòng),采用"kill <pid>"關(guān)閉:

發(fā)現(xiàn)通過(guò)"kill "正常關(guān)閉可以有效調(diào)用鉤子函數(shù),但是"kill -9 "強(qiáng)制關(guān)閉則不會(huì)調(diào)用鉤子函數(shù)。

三、回歸問(wèn)題

經(jīng)過(guò)一系列測(cè)試,驗(yàn)證了JVM鉤子函數(shù)確實(shí)可以實(shí)現(xiàn)我想要的資源關(guān)閉效果。由于我的程序是一個(gè)循環(huán)程序,需要手動(dòng)關(guān)閉,因此可以在關(guān)閉程序的腳本中通過(guò)kill pid的方式進(jìn)行鉤子函數(shù)的調(diào)用。

到此這篇關(guān)于JVM鉤子函數(shù)使用場(chǎng)景的文章就介紹到這了,更多相關(guān)JVM鉤子函數(shù)使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Flink實(shí)戰(zhàn)之實(shí)現(xiàn)流式數(shù)據(jù)去重

    Flink實(shí)戰(zhàn)之實(shí)現(xiàn)流式數(shù)據(jù)去重

    流式數(shù)據(jù)是一種源源不斷產(chǎn)生的數(shù)據(jù),本文探索了一種流式大數(shù)據(jù)的實(shí)時(shí)去重方法,不一定適用于所有場(chǎng)景,不過(guò)或許可以給面對(duì)相似問(wèn)題的你一點(diǎn)點(diǎn)啟發(fā),
    2025-03-03
  • 帶你重新認(rèn)識(shí)Java動(dòng)態(tài)代理

    帶你重新認(rèn)識(shí)Java動(dòng)態(tài)代理

    這篇文章主要為大家介紹了Java的動(dòng)態(tài)代理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2021-11-11
  • Mybatis加載策略的實(shí)現(xiàn)方法

    Mybatis加載策略的實(shí)現(xiàn)方法

    Mybatis中一對(duì)一,一對(duì)多,多對(duì)多關(guān)系的配置及實(shí)現(xiàn),可以實(shí)現(xiàn)對(duì)象的關(guān)聯(lián)查詢(xún)。實(shí)際開(kāi)發(fā)過(guò)程中很多時(shí)候我們并不需要總是在加載用戶(hù)信息時(shí)就一定要加載他的訂單信息,這是就是我們常說(shuō)的延時(shí)加載,本文給大家詳細(xì)介紹實(shí)現(xiàn)方法,一起看看吧
    2022-02-02
  • SpringBoot如何實(shí)現(xiàn)文件下載

    SpringBoot如何實(shí)現(xiàn)文件下載

    這篇文章主要介紹了SpringBoot如何實(shí)現(xiàn)文件下載問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 基于Java驗(yàn)證jwt token代碼實(shí)例

    基于Java驗(yàn)證jwt token代碼實(shí)例

    這篇文章主要介紹了基于Java驗(yàn)證jwt token代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 詳解spring boot配置 ssl

    詳解spring boot配置 ssl

    本篇文章主要介紹了詳解spring boot配置 ssl,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • java中synchronized鎖的升級(jí)過(guò)程

    java中synchronized鎖的升級(jí)過(guò)程

    這篇文章主要介紹了java中synchronized鎖的升級(jí)過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • maven 指定version不生效的問(wèn)題

    maven 指定version不生效的問(wèn)題

    這篇文章主要介紹了maven 指定version不生效的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java中String StringBuffer和StringBuilder的區(qū)別詳解

    java中String StringBuffer和StringBuilder的區(qū)別詳解

    大家好,本篇文章主要講的是java中String StringBuffer和StringBuilder的區(qū)別詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下
    2022-01-01
  • MybatisPlus實(shí)現(xiàn)數(shù)據(jù)權(quán)限隔離的示例詳解

    MybatisPlus實(shí)現(xiàn)數(shù)據(jù)權(quán)限隔離的示例詳解

    Mybatis Plus對(duì)Mybatis做了無(wú)侵入的增強(qiáng),非常的好用,今天就給大家介紹它的其中一個(gè)實(shí)用功能:數(shù)據(jù)權(quán)限插件,感興趣的可以跟隨小編一起了解下
    2024-04-04

最新評(píng)論

南溪县| 磐安县| 集安市| 涿鹿县| 建瓯市| 恭城| 团风县| 莱州市| 伊通| 叶城县| 蒙自县| 裕民县| 来宾市| 德江县| 嘉定区| 云浮市| 卓资县| 湄潭县| 大足县| 石首市| 灵武市| 通化县| 融水| 湟源县| 如皋市| 安顺市| 永兴县| 北流市| 定远县| 肥西县| 北京市| 略阳县| 大宁县| 合阳县| 石棉县| 和龙市| 探索| 巩义市| 宜丰县| 泽库县| 崇明县|