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

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

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

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

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

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

也就是說,線程是可能被重用的,如果線程一旦被重用,而ThreadLocal的數(shù)據(jù)沒有及時重置,就會導(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)致的問題,我們將servlet.tomcat.threads.max設(shè)置為1,這樣每次請求使用的都是同一個線程。

第一次請求接口,數(shù)據(jù)看起來很正常:

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

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

正確使用的姿勢

修正的辦法就是處理完接口之后要及時清理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)雅的處理方式

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

最后

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

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

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

相關(guān)文章

  • SpringBoot多數(shù)據(jù)源配置方式以及報錯問題的解決

    SpringBoot多數(shù)據(jù)源配置方式以及報錯問題的解決

    這篇文章主要介紹了SpringBoot多數(shù)據(jù)源配置方式以及報錯問題的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Spring Data Jpa 自動生成表結(jié)構(gòu)的方法示例

    Spring Data Jpa 自動生成表結(jié)構(gòu)的方法示例

    這篇文章主要介紹了Spring Data Jpa 自動生成表結(jié)構(gòu)的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Mybatis實(shí)現(xiàn)自定義類型轉(zhuǎn)換器TypeHandler的方法

    Mybatis實(shí)現(xiàn)自定義類型轉(zhuǎn)換器TypeHandler的方法

    Mybatis實(shí)現(xiàn)自定義的轉(zhuǎn)換器非常的簡單,只需要三步就可以實(shí)現(xiàn)自定義類型轉(zhuǎn)換器TypeHandler,非常不錯,具有參考借鑒價值,感興趣的朋友一起看下吧
    2016-07-07
  • springboot項目開啟https協(xié)議的項目實(shí)現(xiàn)

    springboot項目開啟https協(xié)議的項目實(shí)現(xiàn)

    本文主要介紹了springboot項目開啟https協(xié)議的項目實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 關(guān)于Java中@SuppressWarnings的正確使用方法

    關(guān)于Java中@SuppressWarnings的正確使用方法

    這篇文章主要介紹了關(guān)于Java中@SuppressWarnings的正確使用方法,@SuppressWarnings注解主要用在取消一些編譯器產(chǎn)生的警告對代碼左側(cè)行列的遮擋,有時候這會擋住我們斷點(diǎn)調(diào)試時打的斷點(diǎn),需要的朋友可以參考下
    2023-05-05
  • java中如何區(qū)分==和equals

    java中如何區(qū)分==和equals

    這篇文章主要介紹了java中如何區(qū)分==和equals,文中講解的非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • SpringMVC中文亂碼踩坑記錄

    SpringMVC中文亂碼踩坑記錄

    這篇文章主要介紹了SpringMVC中文亂碼踩坑記錄,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • Java 精煉解讀方法的定義與使用

    Java 精煉解讀方法的定義與使用

    Java語言中的“方法”(Method)在其他語言當(dāng)中也可能被稱為“函數(shù)”(Function)。對于一些復(fù)雜的代碼邏輯,如果希望重復(fù)使用這些代碼,并且做到“隨時任意使用”,那么就可以將這些代碼放在一個大括號“{}”當(dāng)中,并且起一個名字。使用的時候,直接找到名字調(diào)用即可
    2022-03-03
  • Spring Boot Rest控制器單元測試過程解析

    Spring Boot Rest控制器單元測試過程解析

    這篇文章主要介紹了Spring Boot Rest控制器單元測試過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • java 靜態(tài)鏈表實(shí)現(xiàn)示例詳解

    java 靜態(tài)鏈表實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了java 靜態(tài)鏈表實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06

最新評論