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

不規(guī)范使用ThreadLocal導(dǎo)致bug分析解決

 更新時(shí)間:2023年01月08日 16:46:00   作者:程序員拾山  
這篇文章主要為大家介紹了不規(guī)范使用ThreadLocal導(dǎo)致bug分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

因?yàn)榫€程重用導(dǎo)致的信息錯(cuò)亂的bug

ThreadLocal一般用于線程間的數(shù)據(jù)隔離,通過(guò)將數(shù)據(jù)緩存在ThreadLocal中,可以極大的提升性能。但是,如果錯(cuò)誤的使用Threadlocal,可能會(huì)引起不可預(yù)期的bug,以及造成內(nèi)存泄露。

有時(shí)我們會(huì)在一個(gè)接口中緩存某些數(shù)據(jù)到ThreadLocal中,但是我們要意識(shí)到,處理請(qǐng)求的這些線程是由tomcat提供的,而tomcat提供的線程都是配置在一個(gè)線程池中的。

也就是說(shuō),線程是可能被重用的,如果線程一旦被重用,而ThreadLocal的數(shù)據(jù)沒(méi)有及時(shí)重置,就會(huì)導(dǎo)致數(shù)據(jù)被混亂使用。

以下方的接口為例,先獲取當(dāng)前線程中保存的數(shù)據(jù)信息,將參數(shù)中的name保存到ThreadLocal中以后,再獲取一次。

@GetMapping(value = "/threadLocal")
public ResponseEntity<Object> threadLocal(String name) {
  String before = Thread.currentThread().getName() + ":" + threadLocal.get();
  //先獲取值,理論上應(yīng)該是null
  System.out.println("before:" + before);
  threadLocal.set(name);
  String after = Thread.currentThread().getName() + ":" + threadLocal.get();
  //設(shè)置完參數(shù)值再獲取一次
  System.out.println("after:" + after);
  return ResponseEntity.ok().build();
}

為了盡快復(fù)現(xiàn)線程重用導(dǎo)致的問(wèn)題,我們將servlet.tomcat.threads.max設(shè)置為1,這樣每次請(qǐng)求使用的都是同一個(gè)線程。

第一次請(qǐng)求接口,數(shù)據(jù)看起來(lái)很正常:

但是第二次請(qǐng)求接口時(shí),可以看到線程仍然是http-nio-8080-exec-1,但是before卻打印出了第一次請(qǐng)求的參數(shù)test。

這就是因?yàn)闆](méi)有及時(shí)重置ThreadLocal導(dǎo)致的數(shù)據(jù)錯(cuò)誤。

正確使用的姿勢(shì)

修正的辦法就是處理完接口之后要及時(shí)清理ThreadLocal。

@GetMapping(value = "/threadLocal")
public ResponseEntity<Object> threadLocal(String name) {
  try {
    String before = Thread.currentThread().getName() + ":" + threadLocal.get();
    //先獲取值,理論上應(yīng)該是null
    System.out.println("before:" + before);
    threadLocal.set(name);
    String after = Thread.currentThread().getName() + ":" + threadLocal.get();
    //設(shè)置完參數(shù)值再獲取一次
    System.out.println("after:" + after);
  } finally {
    //清理數(shù)據(jù)
    threadLocal.remove();
  }
  return ResponseEntity.ok().build();
}

更優(yōu)雅的處理方式

可能也有的朋友會(huì)說(shuō),每次都要使用try finally處理線程數(shù)據(jù),未免也太麻煩了。其實(shí),我們可以使用攔截器或者過(guò)濾器自動(dòng)幫我們完成數(shù)據(jù)的初始化以及清理工作。

最后

我們?cè)趯?xiě)業(yè)務(wù)代碼時(shí),正確的理解線程的全生命周期以及執(zhí)行原理,對(duì)我們提升代碼的健壯性其實(shí)很有幫助。有時(shí)我們覺(jué)得底層原理很枯燥乏味,開(kāi)發(fā)業(yè)務(wù)就是寫(xiě)增刪改查,多線程用的也很少,但我們只是沒(méi)有意識(shí)到,我們的代碼一直跑在tomcat提供的線程池中,本身就是一個(gè)多線程的環(huán)境。

除了tomcat的線程池,我們自定義的線程池其實(shí)也會(huì)有這個(gè)問(wèn)題,大家可以看看自己的業(yè)務(wù)代碼是否踩過(guò)這個(gè)坑。

以上就是不規(guī)范使用ThreadLocal導(dǎo)致bug分析解決的詳細(xì)內(nèi)容,更多關(guān)于ThreadLocal bug解決分析的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java中的對(duì)象和對(duì)象引用實(shí)例淺析

    Java中的對(duì)象和對(duì)象引用實(shí)例淺析

    這篇文章主要介紹了Java中的對(duì)象和對(duì)象引用,實(shí)例分析了對(duì)象與對(duì)象引用的概念與相關(guān)使用技巧,需要的朋友可以參考下
    2015-05-05
  • 如何利用Java獲取當(dāng)天的開(kāi)始和結(jié)束時(shí)間

    如何利用Java獲取當(dāng)天的開(kāi)始和結(jié)束時(shí)間

    這篇文章主要介紹了如何使用Java?8的LocalDate和LocalDateTime類(lèi)獲取指定日期的開(kāi)始和結(jié)束時(shí)間,展示了如何通過(guò)這些類(lèi)進(jìn)行日期和時(shí)間的處理,從而簡(jiǎn)化了日期時(shí)間操作,需要的朋友可以參考下
    2025-02-02
  • 詳解如何更改SpringBoot TomCat運(yùn)行方式

    詳解如何更改SpringBoot TomCat運(yùn)行方式

    這篇文章主要介紹了詳解如何更改SpringBoot TomCat運(yùn)行方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • IntelliJ IDEA 安裝 Grep Console插件 自定義控制臺(tái)輸出多顏色格式功能

    IntelliJ IDEA 安裝 Grep Console插件 自定義控制臺(tái)輸出多顏色格式功能

    由于Intellij idea不支持顯示ascii顏色,grep-console插件能很好的解決這個(gè)問(wèn)題,下面就以開(kāi)發(fā)JavaEE項(xiàng)目中,結(jié)合Log4j配置多顏色日志輸出功能,感興趣的朋友一起看看吧
    2020-05-05
  • Spring4如何自定義@Value功能詳解

    Spring4如何自定義@Value功能詳解

    這篇文章主要給大家介紹了關(guān)于Spring4如何自定義@Value功能的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用spring4具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Java PriorityQueue數(shù)據(jù)結(jié)構(gòu)接口原理及用法

    Java PriorityQueue數(shù)據(jù)結(jié)構(gòu)接口原理及用法

    這篇文章主要介紹了Java PriorityQueue數(shù)據(jù)結(jié)構(gòu)接口原理及用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • IDEA2020.2.3中創(chuàng)建JavaWeb工程的完整步驟記錄

    IDEA2020.2.3中創(chuàng)建JavaWeb工程的完整步驟記錄

    這篇文章主要給大家介紹了關(guān)于IDEA2020.2.3中創(chuàng)建JavaWeb工程的完整步驟,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Mybatis中使用萬(wàn)能的Map傳參實(shí)現(xiàn)

    Mybatis中使用萬(wàn)能的Map傳參實(shí)現(xiàn)

    在編程中,有可能遇到我們的實(shí)體類(lèi)或者數(shù)據(jù)庫(kù)中表的字段或參數(shù)過(guò)多的情況,那這時(shí)候用Map傳參是比較理想的選擇,本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解下
    2021-07-07
  • 使用JWT作為Spring?Security?OAuth2的token存儲(chǔ)問(wèn)題

    使用JWT作為Spring?Security?OAuth2的token存儲(chǔ)問(wèn)題

    這篇文章主要介紹了使用JWT作為Spring?Security?OAuth2的token存儲(chǔ),大家經(jīng)常使用的方法有兩種一種是使用JWT作為T(mén)oken傳遞,一種是使用Redis存儲(chǔ)Token,資源服務(wù)器本地訪問(wèn)Redis校驗(yàn)Token,需要的朋友可以參考下
    2021-12-12
  • MyBatis-Plus模糊查詢(xún)特殊字符串轉(zhuǎn)義的實(shí)現(xiàn)

    MyBatis-Plus模糊查詢(xún)特殊字符串轉(zhuǎn)義的實(shí)現(xiàn)

    使用MyBatis中的模糊查詢(xún)時(shí),當(dāng)查詢(xún)關(guān)鍵字中包括有_、\、%時(shí),查詢(xún)關(guān)鍵字失效,本文主要介紹了MyBatis-Plus模糊查詢(xún)特殊字符串轉(zhuǎn)義的實(shí)現(xiàn),感興趣的可以了解一下
    2024-06-06

最新評(píng)論

合水县| 宜良县| 安义县| 上饶市| 万年县| 永定县| 本溪市| 准格尔旗| 邯郸市| 六枝特区| 香河县| 江达县| 五大连池市| 太谷县| 利川市| 绥宁县| 永新县| 楚雄市| 定兴县| 佛学| 霍邱县| 龙山县| 庄浪县| 通海县| 门头沟区| 武定县| 越西县| 五指山市| 平邑县| 花莲市| 岳西县| 宝丰县| 盐津县| 临湘市| 莱西市| 肥乡县| 樟树市| 鹿邑县| 台东市| 丰都县| 延寿县|