聽到問題第一反應應該是併發場景下資料安全的問題,於是clone了他們的專案,對著**開始排查。
使用的是springmvc,每個controller(單例)都繼承於乙個basecontroller,basecontroller實現了iwebcontext介面,注入了request、response物件
類圖:
首先發現問題:controller預設為單例, 故request作為成員變數肯定會在併發情況下出現引數相互覆蓋的問題,解決方式:
//該類其他方法使用request方式,request其實也是放在threadlocal中
去掉request、response成員變數,使用執行緒私有變數,這個問題到此應該解決了? fix之後再測試發現這個問題依然存在。
仔細回顧下**,現在成員變數只有乙個threadlocal 裡邊放的是userinfo資訊。
jdk thread 實現每個執行緒都維護了變數為threadlocals的threadlocal.threadlocalmap。threadlocal set、get方法都是在當前執行緒的threadmap中進行讀寫操作,
threadmap是以:threadlocal物件為key(set操作傳入的key都是同乙個物件,threadlocal解決key重複的演算法,基於乙個0x61cc88647遞增獲取乙個新的hash值&整個table的長度-1),在這個實現下保證了每個執行緒操作的就是當前執行緒的副本。這裡是不會有執行緒安全問題的。
那為什麼還會出現資料相互覆蓋問題呢?
總結:使用一項技術的時候,很多時候,不知道原理,拿來主義直接使用,很可能隱藏著一些風險,可能在某個時段集中爆發出來,這對於線上的專案影響是不容小覷的,我們應該在對技術的使用之後,多去看看使用的技術背後的原理,沒問題學習了知識,發現問題能讓問題盡早暴露
ThreadLocal使用介紹
首先有幾點需要大家清楚的 1 threadlocal 只是對需要儲存的物件的管理,而儲存實際是由當前thread 負責。個人理解為threadlocal 是乙個操作thread.threadlocals 的工具。2 使用threadlocal 可以使物件達到執行緒隔離的目的。同乙個threadloc...
ThreadLocal使用案例
本文藉由併發環境下使用執行緒不安全的 dateformat優化案例,幫助大家理解threadlocal.public class dateutil catch parseexception e 首先分析下 該處的函式parseymdhms 使用了synchronized修飾,意味著該操作是執行緒不安...
Java事務 三 使用ThreadLocal
一.為什麼使用threadlocal 如果涉及到呼叫多個service,那我是不是還得從controller層傳遞connection?從而不會影響其他執行緒中的例項變數,所以threadlocal可以實現執行緒範圍內資料共享。二.如何使用threadlocal 1.寫乙個transactionma...