日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java ThreadLocal的使用詳解

瀏覽:18日期:2022-08-12 15:56:53
目錄1. 應(yīng)用場(chǎng)景1.1. 保障線程安全1.2. 顯示傳遞參數(shù)2. 實(shí)現(xiàn)原理3. 注意事項(xiàng)

ThreadLocal是線程私有的局部變量存儲(chǔ)容器,可以理解成每個(gè)線程都有自己專屬的存儲(chǔ)容器,用來(lái)存儲(chǔ)線程私有變量。ThreadLocal 在日常開(kāi)發(fā)框架中應(yīng)用廣泛,但用不好也會(huì)出現(xiàn)各種問(wèn)題,本文就此講解一下。

1. 應(yīng)用場(chǎng)景

ThreadLocal 的常見(jiàn)應(yīng)用場(chǎng)景有兩種:

多線程并發(fā)場(chǎng)景中,用來(lái)保障線程安全。 處理較為復(fù)雜的業(yè)務(wù)時(shí),使用ThreadLocal代替參數(shù)的顯示傳遞。 1.1. 保障線程安全

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

ThreadLocal是除了加鎖這種同步方式之外的一種,規(guī)避多線程訪問(wèn)出現(xiàn)線程不安全的方法。當(dāng)我們?cè)趧?chuàng)建一個(gè)變量后,如果每個(gè)線程對(duì)其進(jìn)行訪問(wèn)的時(shí)候訪問(wèn)的都是線程自己的變量,這樣就不會(huì)存在線程不安全問(wèn)題。

ThreadLocal是JDK包提供的,它提供線程本地變量,如果創(chuàng)建一個(gè)ThreadLocal變量,那么訪問(wèn)這個(gè)變量的每個(gè)線程都會(huì)有這個(gè)變量的一個(gè)副本,在實(shí)際多線程操作的時(shí)候,操作的是自己本地內(nèi)存中的變量,從而規(guī)避了線程安全問(wèn)題。

1.2. 顯示傳遞參數(shù)

這里舉幾個(gè)例子:

示例1:獲取接口的當(dāng)前請(qǐng)求用戶在后臺(tái)接口業(yè)務(wù)邏輯的全過(guò)程中,如果需要在多個(gè)地方獲取當(dāng)前請(qǐng)求用戶的信息。通常的一種做法就是:在接口請(qǐng)求時(shí),通過(guò)過(guò)濾器、攔截器、AOP等方式,從session或token中獲取當(dāng)前用戶信息,存入ThreadLocal中。

在整個(gè)接口處理過(guò)程中,如果沒(méi)有另外創(chuàng)建線程,都可以直接從ThreadLocal變量中獲取當(dāng)前用戶,而無(wú)需再?gòu)腟ession、token中驗(yàn)證和獲取用戶。這種方案設(shè)計(jì)不僅提高性能,最重要的是將原本復(fù)雜的邏輯和代碼實(shí)現(xiàn),變得簡(jiǎn)潔明了。例如下面的這個(gè)例子:

(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)在過(guò)濾器中設(shè)置變量值:

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

(3)獲取當(dāng)前用戶信息

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

示例2:spring框架中保證數(shù)據(jù)庫(kù)事務(wù)在同一個(gè)連接下執(zhí)行

要想實(shí)現(xiàn)jdbc事務(wù), 就必須是在同一個(gè)連接對(duì)象中操作,多個(gè)連接下事務(wù)就會(huì)不可控,需要借助分布式事務(wù)完成。那spring框架如何保證數(shù)據(jù)庫(kù)事務(wù)在同一個(gè)連接下執(zhí)行的呢?

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

2. 實(shí)現(xiàn)原理

ThreadLocal類提供set/get方法存儲(chǔ)和獲取value值,但實(shí)際上ThreadLocal類并不存儲(chǔ)value值,真正存儲(chǔ)是靠ThreadLocalMap這個(gè)類。

每個(gè)線程實(shí)例都對(duì)應(yīng)一個(gè)TheadLocalMap實(shí)例,我們可以在同一個(gè)線程里實(shí)例化很多個(gè)ThreadLocal來(lái)存儲(chǔ)很多種類型的值,這些ThreadLocal實(shí)例分別作為key,對(duì)應(yīng)各自的value,最終存儲(chǔ)在Entry table數(shù)組中。我們看看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的邏輯比較簡(jiǎn)單,就是獲取當(dāng)前線程的ThreadLocalMap,然后往map里添加KV,K是當(dāng)前ThreadLocal實(shí)例,V是我們傳入的value。這里需要注意一下,map的獲取是需要從Thread類對(duì)象里面取,看一下Thread類的定義。

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

Thread類維護(hù)了一個(gè)ThreadLocalMap的變量引用。

因此,我們可以得出如下結(jié)論:

每個(gè)線程是一個(gè)Thread實(shí)例,其內(nèi)部維護(hù)一個(gè)threadLocals的實(shí)例成員,其類型是ThreadLocal.ThreadLocalMap。 ThreadLocal本身并不是一個(gè)容器,我們存取的value實(shí)際上存儲(chǔ)在ThreadLocalMap中,ThreadLocal只是作為TheadLocalMap的key。 3. 注意事項(xiàng)

ThreadLocal實(shí)例有提供remove()方法,用于回收對(duì)象,清除對(duì)應(yīng)的內(nèi)存占用。這個(gè)方法通常容易被忽略,而導(dǎo)致出現(xiàn)了各種問(wèn)題。如下面幾種:

線程復(fù)用:在“獲取接口的當(dāng)前請(qǐng)求用戶”的例子中,Tomcat中是通過(guò)線程池來(lái)處理用戶請(qǐng)求的,而線程池中線程是復(fù)用的。肯定會(huì)出現(xiàn)一個(gè)線程前后被不同用戶的接口請(qǐng)求復(fù)用的情況,因此需要對(duì)用過(guò)的ThreaLocal變量進(jìn)行覆蓋或清除。 內(nèi)存溢出:由于ThreadLocalMap的生命周期跟Thread一樣長(zhǎng),如果創(chuàng)建的ThreadLocal變量很多,即對(duì)應(yīng)的key占用的內(nèi)存很大,但卻沒(méi)有手動(dòng)刪除,到了一定程度就會(huì)導(dǎo)致內(nèi)存泄漏。

以上就是Java ThreadLocal的使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Java ThreadLocal的使用的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品日韩欧美一区| 国产一区亚洲| 在线观看视频免费一区二区三区| 亚洲欧美一区在线| 亚洲电影有码| 亚洲综合色婷婷在线观看| 国产偷自视频区视频一区二区| 欧美一级精品| 亚洲综合欧美| 婷婷精品在线观看| 国产麻豆一区| 国产精品久久观看| 欧美在线观看视频一区| 国产精品视区| 日韩成人午夜精品| 久久免费视频66| 中文在线资源| 国产综合亚洲精品一区二| 自拍日韩欧美| 亚洲理论在线| 国产精品一区免费在线| 国产一区二区三区精品在线观看| 国产一区二区三区四区大秀 | 欧美特黄a级高清免费大片a级| 日韩视频一区| 日韩av中文字幕一区二区三区| 国产精品22p| 热三久草你在线| 亚洲激情欧美| 国产欧美一区二区三区米奇| 国产 日韩 欧美 综合 一区| 亚洲天堂成人| 午夜天堂精品久久久久| 国产精品久久久久久久久久齐齐| 成人精品久久| 精品91久久久久| 日韩国产91| 精品国产乱码久久久久久1区2匹| 91精品综合| 69堂精品视频在线播放| 亚洲黄色中文字幕| 久久亚洲二区| 久久久久亚洲精品中文字幕| 999国产精品永久免费视频app| 亚洲日本国产| 天堂中文av在线资源库| 中文字幕中文字幕精品| 精品国产美女a久久9999| 99在线精品视频在线观看| 国产人成精品一区二区三| 天堂日韩电影| 日本不卡在线视频| 午夜欧美巨大性欧美巨大| 四虎成人精品一区二区免费网站| www.51av欧美视频| 免费成人在线影院| 久久中文视频| 国产精品探花在线观看| 99日韩精品| 成人国产精选| 婷婷久久免费视频| 亚洲一级影院| 欧美国产另类| 久热精品在线| 国产一区二区三区免费在线| 手机精品视频在线观看| 日本久久综合| 欧美亚洲三级| 另类国产ts人妖高潮视频| 欧美xxxx中国| 欧美日韩午夜| 蘑菇福利视频一区播放| 成人片免费看| 国产精品午夜一区二区三区| 日韩在线一区二区| 日韩成人亚洲| 精品视频自拍| 日韩高清三区| 中文在线一区| 日韩精品欧美| 欧美极品中文字幕| 亚洲丝袜美腿一区| 欧美一区二区三区激情视频 | 国产精品超碰| 一区二区三区网站| 激情欧美国产欧美| 色婷婷色综合| 国产精久久久| 天堂俺去俺来也www久久婷婷| 国产精品av一区二区| 成人在线视频免费看| 国产精品一区二区三区av| 蜜臀精品久久久久久蜜臀| 久久精品99久久无色码中文字幕| 日韩av一区二区三区| 免费看欧美美女黄的网站| 亚洲成人三区| 91精品一区二区三区综合在线爱| 成年男女免费视频网站不卡| 国产精品mv在线观看| 97久久亚洲| 亚洲一区二区三区在线免费| 最新亚洲激情| 午夜久久久久| 五月婷婷亚洲| 91精品一区二区三区综合| 涩涩av在线| 久久精品福利| 美女尤物国产一区| 91福利精品在线观看| 日本亚州欧洲精品不卡| 日韩精品一级中文字幕精品视频免费观看| 国产一区二区中文| 婷婷激情综合| 久久国产成人午夜av影院宅| 国产精品久久久久av电视剧| 国产精品久久久久av电视剧| 日韩成人精品一区二区| 国产成人免费| 国产精品毛片久久| 日韩精品dvd| 久久精品国产99久久| 99精品视频在线观看免费播放| 人人精品亚洲| 99免费精品| 亚洲电影在线一区二区三区| 国精品一区二区| 亚洲精品网址| 久久亚洲一区| 亚洲精品欧美| 欧美私人啪啪vps| 久久精品免视看国产成人| 国产不卡av一区二区| 欧洲精品一区二区三区| 激情婷婷久久| 视频精品一区二区| 日韩国产欧美视频| 麻豆久久久久久| 日韩中文在线电影| 999久久久91| 亚洲一卡久久| 青草久久视频| 欧美国产中文高清| 亚洲黄色免费看| 欧美在线亚洲| 日本亚州欧洲精品不卡| 国产精品白丝一区二区三区| 高清一区二区| 99国产精品私拍| 婷婷综合国产| 国产精品极品国产中出| 黄色在线观看www| 国内精品福利| 亚洲香蕉久久| 国产极品一区| 亚洲午夜精品久久久久久app| 美女尤物久久精品| 国产剧情一区二区在线观看| 中文字幕人成乱码在线观看| 国模 一区 二区 三区| 一级欧美视频| 美女毛片一区二区三区四区最新中文字幕亚洲 | 精品一区三区| 日本不卡一区二区三区| 国产精品草草| 国产在线日韩| 国产日韩欧美一区二区三区| 欧洲av不卡| 亚洲精品国模| 欧美精品aa| 好看的av在线不卡观看| 国产日韩欧美一区在线| 久久精品国语| 欧美亚洲三区| 欧美在线观看视频一区| 久久国产尿小便嘘嘘| 99精品小视频| 国产精品毛片久久久| 婷婷六月综合| 久久av影院| 99国产精品99久久久久久粉嫩| 国产精品久久久久久久免费软件| 久久一区二区三区电影| 国产亚洲欧美日韩精品一区二区三区 | 色网在线免费观看| 综合国产在线| 超碰99在线| 综合国产在线| 秋霞国产精品| 国产伦理一区| 欧美专区一区二区三区| 国产成人久久| 日本精品另类| 黄色日韩在线| 国产传媒在线| 欧美精品观看| 99国产精品| 亚洲最新无码中文字幕久久| 日本不卡中文字幕| 9国产精品视频|