成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Java ThreadLocal的使用詳解

瀏覽:5日期:2022-08-12 15:56:53
目錄1. 應用場景1.1. 保障線程安全1.2. 顯示傳遞參數2. 實現原理3. 注意事項

ThreadLocal是線程私有的局部變量存儲容器,可以理解成每個線程都有自己專屬的存儲容器,用來存儲線程私有變量。ThreadLocal 在日常開發框架中應用廣泛,但用不好也會出現各種問題,本文就此講解一下。

1. 應用場景

ThreadLocal 的常見應用場景有兩種:

多線程并發場景中,用來保障線程安全。 處理較為復雜的業務時,使用ThreadLocal代替參數的顯示傳遞。 1.1. 保障線程安全

多線程訪問同一個共享變量的時候容易出現并發問題,特別是多個線程對一個變量進行寫入的時候,為了保證線程安全,一般使用者在訪問共享變量的時候需要進行額外的同步措施才能保證線程安全性,如:synchronized、Lock之類的鎖。

ThreadLocal是除了加鎖這種同步方式之外的一種,規避多線程訪問出現線程不安全的方法。當我們在創建一個變量后,如果每個線程對其進行訪問的時候訪問的都是線程自己的變量,這樣就不會存在線程不安全問題。

ThreadLocal是JDK包提供的,它提供線程本地變量,如果創建一個ThreadLocal變量,那么訪問這個變量的每個線程都會有這個變量的一個副本,在實際多線程操作的時候,操作的是自己本地內存中的變量,從而規避了線程安全問題。

1.2. 顯示傳遞參數

這里舉幾個例子:

示例1:獲取接口的當前請求用戶在后臺接口業務邏輯的全過程中,如果需要在多個地方獲取當前請求用戶的信息。通常的一種做法就是:在接口請求時,通過過濾器、攔截器、AOP等方式,從session或token中獲取當前用戶信息,存入ThreadLocal中。

在整個接口處理過程中,如果沒有另外創建線程,都可以直接從ThreadLocal變量中獲取當前用戶,而無需再從Session、token中驗證和獲取用戶。這種方案設計不僅提高性能,最重要的是將原本復雜的邏輯和代碼實現,變得簡潔明了。例如下面的這個例子:

(1)定義ThreadLocal變量:UserProfileThread.java

public class UserProfileThread { private static ThreadLocal<UserProfile> USER_PROFILE_TL =new ThreadLocal<>(); public static void setUserProfile(UserProfile userProfile){USER_PROFILE_TL.set(userProfile); } public static UserProfile getUserProfile() {return USER_PROFILE_TL.get(); } public static String getCurrentUser() {return Optional.ofNullable(USER_PROFILE_TL.get()).map(UserProfile::getUid).orElse(UserProfile.ANONYMOUS_USER); }}

(2)在過濾器中設置變量值:

@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {UserProfile userProfile = null;// ... 驗證和獲取用戶信息 userProfileUserProfileThread.setUserProfile(userProfile);filterChain.doFilter(servletRequest, servletResponse); }

(3)獲取當前用戶信息

//獲取當前用戶String uid=UserProfileThread.getCurrentUser();//獲取當前用戶對象UserProfile user=UserProfileThread.getUserProfile();

示例2:spring框架中保證數據庫事務在同一個連接下執行

要想實現jdbc事務, 就必須是在同一個連接對象中操作,多個連接下事務就會不可控,需要借助分布式事務完成。那spring框架如何保證數據庫事務在同一個連接下執行的呢?

DataSourceTransactionManager 是spring的數據源事務管理器,它會在你調用getConnection()的時候從數據庫連接池中獲取一個connection, 然后將其與ThreadLocal綁定,事務完成后解除綁定。這樣就保證了事務在同一連接下完成。

2. 實現原理

ThreadLocal類提供set/get方法存儲和獲取value值,但實際上ThreadLocal類并不存儲value值,真正存儲是靠ThreadLocalMap這個類。

每個線程實例都對應一個TheadLocalMap實例,我們可以在同一個線程里實例化很多個ThreadLocal來存儲很多種類型的值,這些ThreadLocal實例分別作為key,對應各自的value,最終存儲在Entry table數組中。我們看看ThreadLocal的set方法:

public class ThreadLocal<T> { public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) map.set(this, value);else createMap(t, value); } ThreadLocalMap getMap(Thread t) {return t.threadLocals; } void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue); } // 省略其他方法}

set的邏輯比較簡單,就是獲取當前線程的ThreadLocalMap,然后往map里添加KV,K是當前ThreadLocal實例,V是我們傳入的value。這里需要注意一下,map的獲取是需要從Thread類對象里面取,看一下Thread類的定義。

public class Thread implements Runnable { ThreadLocal.ThreadLocalMap threadLocals = null; //省略其他}

Thread類維護了一個ThreadLocalMap的變量引用。

因此,我們可以得出如下結論:

每個線程是一個Thread實例,其內部維護一個threadLocals的實例成員,其類型是ThreadLocal.ThreadLocalMap。 ThreadLocal本身并不是一個容器,我們存取的value實際上存儲在ThreadLocalMap中,ThreadLocal只是作為TheadLocalMap的key。 3. 注意事項

ThreadLocal實例有提供remove()方法,用于回收對象,清除對應的內存占用。這個方法通常容易被忽略,而導致出現了各種問題。如下面幾種:

線程復用:在“獲取接口的當前請求用戶”的例子中,Tomcat中是通過線程池來處理用戶請求的,而線程池中線程是復用的。肯定會出現一個線程前后被不同用戶的接口請求復用的情況,因此需要對用過的ThreaLocal變量進行覆蓋或清除。 內存溢出:由于ThreadLocalMap的生命周期跟Thread一樣長,如果創建的ThreadLocal變量很多,即對應的key占用的內存很大,但卻沒有手動刪除,到了一定程度就會導致內存泄漏。

以上就是Java ThreadLocal的使用詳解的詳細內容,更多關于Java ThreadLocal的使用的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
高清不卡在线观看av| 亚洲自啪免费| 欧美国产一区二区在线观看| 国产精品一区二区欧美| 国产91丝袜在线播放0| 亚洲视频一区二区在线观看| 日本韩国精品一区二区在线观看| 91浏览器打开| 极品美女销魂一区二区三区| ...中文天堂在线一区| 欧美一区二区久久久| 亚洲欧美日韩在线观看a三区| 99热99精品| 日本午夜精品一区二区三区电影| 免费人成在线不卡| 亚洲欧美在线另类| 日韩亚洲欧美成人一区| 性色av一区二区怡红| 91麻豆国产香蕉久久精品| 奇米影视一区二区三区小说| 综合电影一区二区三区 | 欧美本精品男人aⅴ天堂| 国产色综合网| 91免费观看视频在线| 久久er99精品| 亚洲综合在线电影| 国产亚洲精品aa| 欧美日韩大陆在线| 免费永久网站黄欧美| 国产一区免费视频| 成人av综合在线| 麻豆精品视频在线| 一区二区欧美在线观看| 91亚洲资源网| 国产高清无密码一区二区三区| 天天爽夜夜爽夜夜爽精品视频| 国产精品福利一区二区三区| 久久亚洲一区二区三区四区| 欧美挠脚心视频网站| av不卡在线看| 欧美久久一级| 成人av在线播放网址| 美腿丝袜亚洲综合| 亚洲一区二区三区四区在线 | 亚洲欧洲日韩综合二区| 成人黄色电影在线| 激情综合亚洲精品| 日韩黄色小视频| 一区二区三区高清在线| 亚洲国产精品精华液2区45| 日韩一区二区不卡| 欧美性生活久久| 麻豆91精品| 亚洲毛片视频| 在线观看成人av电影| 欧美日韩精品| 91在线观看高清| eeuss鲁片一区二区三区在线看| 韩国av一区二区三区四区| 亚洲一二三专区| 亚洲欧美电影院| 中文字幕乱码日本亚洲一区二区 | 尤妮丝一区二区裸体视频| 91亚洲永久精品| 国产91综合网| 国产乱码一区二区三区| 免费成人美女在线观看.| 亚洲韩国精品一区| 亚洲美女少妇撒尿| 一区在线中文字幕| 欧美激情在线一区二区三区| www激情久久| 欧美精品一区二区三区高清aⅴ| 91精品国产综合久久精品图片 | 亚洲va欧美va国产va天堂影院| 亚洲欧美二区三区| 亚洲色图欧美在线| 1024成人网色www| 亚洲色图欧洲色图婷婷| 亚洲日本中文字幕区| 一色桃子久久精品亚洲| 亚洲视频在线一区观看| 国产精品久久国产精麻豆99网站| 国产欧美一区二区精品秋霞影院 | 日本va欧美va精品| 日本不卡高清视频| 天堂成人免费av电影一区| 亚洲国产日韩av| 午夜精品视频在线观看| 日本在线播放一区二区三区| 美女精品自拍一二三四| 麻豆精品久久精品色综合| 麻豆久久久久久久| 精品一区二区免费| 激情久久五月天| 国产一区二区三区黄视频| 国产精品 日产精品 欧美精品| 国产精品自拍在线| 成人精品视频一区| 欧美不卡高清| 亚洲小说区图片区| 国产日韩久久| 色综合久久天天| 欧美色图免费看| 日韩午夜电影在线观看| 久久网这里都是精品| 国产嫩草影院久久久久| 亚洲欧洲日本在线| 亚洲图片自拍偷拍| 美女mm1313爽爽久久久蜜臀| 国产一区二区三区免费看| 成人av影院在线| 国内精品久久久久久久97牛牛| 18成人免费观看视频| 亚洲永久视频| 欧美综合一区二区三区| 欧美色图片你懂的| 日韩精品一区二区三区视频在线观看 | 日韩精品乱码av一区二区| 久久av老司机精品网站导航| 国产乱色国产精品免费视频| 成人高清视频在线观看| 欧美激情国产日韩| 亚洲人成人一区二区三区| 国内外成人免费视频| 国产视频一区三区| 欧美三级电影网| 久久一日本道色综合| 亚洲欧美欧美一区二区三区| 亚洲一区二区三区四区在线免费观看 | 激情偷乱视频一区二区三区| 国产大片一区二区| 欧美xx69| 嫩草成人www欧美| 91精品国产综合久久久久| 中文字幕精品一区二区精品绿巨人 | 亚洲久草在线视频| 免费观看成人鲁鲁鲁鲁鲁视频| 国产电影精品久久禁18| 欧美777四色影| 羞羞答答国产精品www一本| 91精品国产综合久久精品性色| 中文天堂在线一区| 日韩av电影免费观看高清完整版 | 精品999在线播放| 亚洲麻豆国产自偷在线| 人禽交欧美网站| av电影在线不卡| 日韩亚洲不卡在线| 欧美精品在线一区二区三区| 国产日韩欧美不卡在线| 一区二区三区在线视频免费观看| 美腿丝袜一区二区三区| 色综合一个色综合亚洲| 免费欧美在线| 欧美电影免费提供在线观看| 日韩美女视频一区二区| 久久99久久99| 欧美日本一区二区视频在线观看 | 717成人午夜免费福利电影| 国产女人18毛片水真多成人如厕| 亚洲mv在线观看| 精品播放一区二区| 午夜欧美电影在线观看| 成人精品电影在线观看| 亚洲自拍高清| 久久午夜色播影院免费高清 | 欧美一区二区三区公司| ㊣最新国产の精品bt伙计久久| 国产欧美日韩综合一区在线观看 | 午夜精品福利在线| 成人av网站免费| 亚洲一区二区在线看| 日韩片之四级片| 亚洲免费看黄网站| 国产成人亚洲综合a∨婷婷图片| 影音先锋在线一区| 91精品国产手机| 亚洲一卡二卡三卡四卡五卡| av电影天堂一区二区在线观看| 玖玖在线精品| 国产精品美女久久久久高潮| 久久精品国产久精国产| 狠狠爱www人成狠狠爱综合网| 欧美精品三级日韩久久| 亚洲精品国产无天堂网2021| 成人午夜电影网站| 久久久久久久久一区二区| 欧美国产日韩亚洲一区| 狠狠色丁香久久婷婷综合丁香| 亚洲色图制服诱惑 | 一区二区三区视频在线看| 成人精品亚洲人成在线| 一本久道久久综合中文字幕 | 91麻豆国产福利精品| 在线影视一区二区三区| 中文字幕中文字幕一区二区| 国产成人av电影| 米奇777在线欧美播放| 欧美国产一区二区|