日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

?Thread Local深度解析,你學會了嗎?

來源: 責編: 時間:2024-02-05 17:18:42 270觀看
導讀今天,有個朋友問我說他想在并發條件下統計接口的耗時以及日期,并做一個記錄在最后統一保存,這里我就直接想到了ThreadLocal,其實我用ThreadLocal的場景還挺多的,畢竟項目需要,其實一直都想對ThreadLocal做一個總結,擇日不如

今天,有個朋友問我說他想在并發條件下統計接口的耗時以及日期,并做一個記錄在最后統一保存,這里我就直接想到了ThreadLocal,其實我用ThreadLocal的場景還挺多的,畢竟項目需要,其實一直都想對ThreadLocal做一個總結,擇日不如撞日就現在動手吧。Uv028資訊網——每日最新資訊28at.com

ThreadLocal概念

ThreadLocal也叫做本地線程變量,ThreadLocal中填充的是當前線程的變量,該變量對其他線程是隔離的,ThreadLocal在每個線程中都創建了一個變量副本,所以每個線程中的ThreadLocal都是一個獨立的副本,自己可以訪問自己線程內部的副本變量互不干擾。Uv028資訊網——每日最新資訊28at.com

ThreadLocal使用場景

ThreadLocal的使用也要看情況來定,按個人理解ThreadLocal大致會使用到以下場景:Uv028資訊網——每日最新資訊28at.com

  • 需要全局獲取變量(保證這個變量在全局中的一致性)
  • 需要解決線程安全的場景(例如:記錄每個請求的一些信息,保存到日志表中)
  • 父子線程需要共享數據(例如:需要子線程的結果回調給父線程,如何保存它的唯一性)

說白了ThreadLocal就是做數據隔離,每條線程的ThreadLocal都是隔離的互不干擾,其實就是為了防止多線程環境下變量被其他線程篡改,只要記住這點在工作中什么場景下會使用到就一目了然了。Uv028資訊網——每日最新資訊28at.com

實際上Spring就是采用了Threadlocal來實現單個線程中的數據庫操作使用的是同一個數據庫連接,采用Threadlocal可以使業務層使用事務的時候不需要去管理connection對象,通過傳播級別就能管理多個事務配置之間的切換,掛起和恢復。Uv028資訊網——每日最新資訊28at.com

Spring框架里面就是用的ThreadLocal來實現這種隔離,主要是在TransactionSynchronizationManager這個類里面,代碼如下所示:Uv028資訊網——每日最新資訊28at.com

private static final Log logger = LogFactory.getLog(TransactionSynchronizationManager.class);private static final ThreadLocal<Map<Object, Object>> resources =  new NamedThreadLocal<>("Transactional resources");private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =  new NamedThreadLocal<>("Transaction synchronizations");private static final ThreadLocal<String> currentTransactionName =  new NamedThreadLocal<>("Current transaction name");

Uv028資訊網——每日最新資訊28at.com

注意:在Spring5.2以后的版本Spring事務隔離從ThreadLocal換成了Mono響應式編程來實現隔離。Uv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

ThreadLocal源碼分析

圖片圖片Uv028資訊網——每日最新資訊28at.com

從源碼上看其實ThreadLocal的set方法并不復雜
  1. 獲取當前線程對象Thread.currentThread();
  2. 獲取線程變量ThreadLocalMap map = getMap(t);
  3. 如果不為空則賦值map.set(this,value);
  4. 如果為空,初始化該線程對象的map變量,其中key為當前的threadlocal變量createMap(t,value);
再看看ThreadLocal的get方法

圖片圖片Uv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

  • 返回當前線程變量的副本中的值,如果該變量沒有當前線程的值,則先調用initialValue方法的返回值
  • initialValue方法中繼續獲取當前線程變量(Key為當前線程)而Value設置為null
  • 如果當前線程副本變量為空那么重新創建當前線程的Map(Key為當前線程,Value為null)
ThreadLocal如何做到線程隔離?

上面分析了ThreadLocal的set()和get()源碼,在通過get()方法獲取當前線程中副本變量為null那么直接創建一個ThreadLocalMap:Uv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

從這里入手,看一下t.threadLocalsUv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

注釋說得很清楚:ThreadLocal屬于當前這個線程的。Uv028資訊網——每日最新資訊28at.com

注意:這個ThreadLocalMap是一個靜態內部類Uv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

ThreadLocalMap is a customized hash map suitable only for maintaining thread local values. No operations are exported outside of the ThreadLocal class. The class is package private to allow declaration of fields in class Thread. To help deal with very large and long-lived usages, the hash table entries use WeakReferences for keys. However, since reference queues are not used, stale entries are guaranteed to be removed only when the table starts running out of space.Uv028資訊網——每日最新資訊28at.com

到此為止其實ThreadLocal的數據隔離的真相就出來了,說白了每個線程Thread都維護了自己的一個threadLocals變量,當線程創建ThreadLocal的時候,實際上數據是存在自己的線程Thread的threadLocals變量里面,可以看出來這個ThreadLocalMap這個類只有一份,在線程中,所以實現了線程之間的隔離。Uv028資訊網——每日最新資訊28at.com

ThreadLocalMap底層原理

圖片圖片Uv028資訊網——每日最新資訊28at.com

雖然看著ThreadLocalMap很像是HashMap,實際上并沒有實現Map接口,而是它的內部類Entry繼承了WeakReference這個弱引用,也就是說不存在鏈表的關系了。Uv028資訊網——每日最新資訊28at.com

接下來我們來看一下ThreadLocalMap的set()方法(這里圖片沒有截全):Uv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

ThreadLocalMap在存儲的時候每次都會給每一個ThreadLocal對象一個threadLocalHashCode,在插入過程中,根據ThreadLocal對象的hash值,定位到table中的位置i,int i = key.threadLocalHashCode & (len - 1);Uv028資訊網——每日最新資訊28at.com

接下來判斷如果當前位置為null,就初始化一個Entry對象放在位置上Uv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

如果當前位置i不為空,又剛好這個Entry對象的key正好是即將設置的key,那么就覆蓋Entry中的valueUv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

如果位置i不為null并且key不等于 entry,那么就找下一個空位置,直到位置為空為止然后存放。Uv028資訊網——每日最新資訊28at.com

在get的時候就會根據ThreadLocal對象的Hash值,定位到相應位置,然后判斷該位置Entry對象中的key是否和get的key一致,如果不一致,就判斷下個位置。Uv028資訊網——每日最新資訊28at.com

如何共享ThreadLocal中的數據?

使用 InheritableThreadLocal可以實現多個線程訪問ThreadLocal的值。Uv028資訊網——每日最新資訊28at.com

問題是它們之間是如何實現傳遞的?

其實邏輯很簡單,繼續看Thread的源碼,看下初始化的時候Thread.init做了什么操作:Uv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

如果線程的inheritThreadLocals變量不為空的話,并且父線程的inheritThreadLocals不為空的話,就把線程的inheritThreadLocals給當前線程的inheritThreadLocalsUv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

關于ThreadLocal內存泄露

ThreadLocal使用不當也會出現問題:那就是內存泄露Uv028資訊網——每日最新資訊28at.com

繼續查看最開始存儲數據的Entry類的源碼Uv028資訊網——每日最新資訊28at.com

圖片圖片Uv028資訊網——每日最新資訊28at.com

其實文檔已經說得很直白了:Uv028資訊網——每日最新資訊28at.com

Note that null keys (i.e. entry.get()* == null 如果 key threadlocal 為 null 了,這個 entry 就可以清除了。Uv028資訊網——每日最新資訊28at.com

ThreadLocal是一個弱引用,當為null時,會被當成垃圾回收 。Uv028資訊網——每日最新資訊28at.com

造成內存泄露的原因在于ThreadLocal為null,也就是要被垃圾回收器回收了,但是此時我們的ThreadLocalMap(thread 的內部屬性)生命周期和Thread的一樣,它不會回收,這時候就出現了一個現象。那就是ThreadLocalMap的key沒了,但是value還在,這就造成了內存泄漏。Uv028資訊網——每日最新資訊28at.com

再詳細點來說,ThreadLocal在沒有外部強引用時,發生GC時會被回收,如果創建ThreadLocal的線程一直持續運行,那么這個Entry對象中的value就有可能一直得不到回收,發生內存泄露。Uv028資訊網——每日最新資訊28at.com

就比如線程池里面的線程,線程都是復用的,那么之前的線程實例處理完之后,出于復用的目的線程依然存活,所以,ThreadLocal設定的value值被持有,導致內存泄露。Uv028資訊網——每日最新資訊28at.com

按照道理一個線程使用完,ThreadLocalMap是應該要被清空的,但是現在線程被復用了。Uv028資訊網——每日最新資訊28at.com

解決辦法:

每次在使用完ThreadLocal的時候一定要remove。Uv028資訊網——每日最新資訊28at.com

為什么ThreadLocal要使用弱引用?

如果使用強引用,當ThreadLocal 對象的引用(強引用)被回收了,ThreadLocalMap本身依然還持有ThreadLocal的強引用,如果沒有手動刪除這個key ,則ThreadLocal不會被回收,所以只要當前線程不消亡,ThreadLocalMap引用的那些對象就不會被回收, 可以認為這導致Entry內存泄漏。Uv028資訊網——每日最新資訊28at.com

  • 強引用:普通的引用,強引用指向的對象不會被回收。
  • 軟引用:僅有軟引用指向的對象,只有發生gc且內存不足,才會被回收。
  • 弱引用:僅有弱引用指向的對象,只要發生gc就會被回收。

本文鏈接:http://m.www897cc.com/showinfo-26-74189-0.html?Thread Local深度解析,你學會了嗎?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 巴可可立享重磅新品 —— 無線視頻會議一體機,多合一,“會”更強

下一篇: Go 中如何檢查文件是否存在?可能產生競態條件?

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
国产亚洲一区在线| 欧美chengren| 亚洲一区国产一区| 亚洲欧美日韩国产另类专区| 亚洲性线免费观看视频成熟| 欧美一区视频在线| 久久久精品国产99久久精品芒果| 另类天堂av| 欧美日韩亚洲国产精品| 国产精品久久一区主播| 国产一区二区毛片| 亚洲美女在线国产| 久久国产精品第一页| 亚洲国产精品久久久久秋霞蜜臀| 亚洲理伦电影| 午夜精品亚洲| 欧美韩国一区| 国产精品一香蕉国产线看观看| 亚洲大胆在线| 香蕉久久夜色精品| 欧美精品一区二区三区视频| 国产亚洲毛片| 亚洲在线播放| 欧美日韩综合精品| 一区二区在线看| 欧美日韩国产欧| 国内精品久久久久久久影视麻豆| 亚洲一区二区三区在线| 看欧美日韩国产| 国产日韩欧美另类| 亚洲一区二区在线播放| 欧美激情第三页| 怡红院精品视频| 久久久不卡网国产精品一区| 国产精品欧美日韩一区二区| 日韩午夜黄色| 欧美精品九九99久久| 在线免费不卡视频| 麻豆乱码国产一区二区三区| 国产伦精品一区二区三区在线观看| 一区二区三区高清在线观看| 欧美日本不卡高清| 日韩视频在线一区二区三区| 欧美精品在欧美一区二区少妇| 亚洲高清久久| 女主播福利一区| 激情欧美国产欧美| 久久这里只精品最新地址| 精品1区2区3区4区| 免费视频一区二区三区在线观看| 在线观看欧美日韩| 欧美国产激情二区三区| 亚洲综合日韩在线| 亚洲精品日韩久久| 久久视频在线看| 国产精品网曝门| 午夜日韩电影| 洋洋av久久久久久久一区| 国产精品自在在线| 亚洲已满18点击进入久久| 国产精品美女久久久免费 | 亚洲第一页自拍| 欧美国产视频在线观看| 一本一本大道香蕉久在线精品| 欧美日韩国产999| 宅男在线国产精品| 国产欧美日韩三级| 欧美成年人视频网站欧美| 1000部国产精品成人观看| 欧美日韩精品二区第二页| 欧美一区二区三区另类 | 伊人久久大香线| 欧美日韩亚洲一区在线观看| 欧美一级播放| 亚洲三级影院| 一色屋精品视频在线观看网站| 欧美日韩精品在线| 久久福利毛片| 中文在线资源观看视频网站免费不卡| 国产欧美一区二区白浆黑人| 猛干欧美女孩| 久久激五月天综合精品| 亚洲一区二区三区视频| 日韩天堂在线观看| 一本高清dvd不卡在线观看| 欧美一区二区三区啪啪| 亚洲欧美日韩视频二区| 午夜电影亚洲| 久久久99免费视频| 久久久久久有精品国产| 午夜在线a亚洲v天堂网2018| 99在线观看免费视频精品观看| 国产有码一区二区| 国产精品久久久一区麻豆最新章节| 欧美成年人视频| 久久夜色精品国产欧美乱| 欧美一区影院| 亚洲在线观看免费视频| 亚洲午夜激情网页| 亚洲图片欧美一区| 亚洲中字黄色| 欧美一区二区三区男人的天堂| 亚洲欧美日韩成人| 欧美一级在线亚洲天堂| 狂野欧美激情性xxxx欧美| 久久蜜臀精品av| 美女诱惑一区| 欧美精品v日韩精品v国产精品| 麻豆av福利av久久av| 欧美国产视频在线观看| 欧美激情在线播放| 欧美高清视频在线播放| 欧美黄在线观看| 欧美日韩1080p| 欧美视频一区二区三区四区| 国产精品成人aaaaa网站| 国产精品成人在线| 国产日韩欧美视频| 国产精品一二三视频| 国产自产在线视频一区| 韩国av一区| 亚洲精品久久久久中文字幕欢迎你| 一区二区三区欧美日韩| 欧美专区在线观看一区| 欧美+日本+国产+在线a∨观看| 欧美日韩一区二区三区在线| 精品不卡一区| 欧美中文字幕久久| 国产精品啊啊啊| 一区二区电影免费观看| 免费日韩成人| 国产综合18久久久久久| 在线播放日韩专区| 亚洲午夜久久久久久尤物| 久久一区二区三区国产精品| 欧美日韩亚洲一区二区三区在线 | 亚洲欧美色一区| 欧美黄色片免费观看| 韩国久久久久| 亚洲一区二区三区国产| 久久久久久久网站| 国产精品毛片a∨一区二区三区| 亚洲国产一区二区三区高清| 香蕉久久夜色精品| 欧美日韩视频在线观看一区二区三区| 国产亚洲在线观看| 小嫩嫩精品导航| 欧美视频福利| 亚洲美女av网站| 欧美国产第一页| 91久久久久久久久| 久久在线91| 亚洲国产乱码最新视频| 久久国产一区| 国产一区二区av| 亚洲欧美国产77777| 国产精品九九| 亚洲欧美激情一区| 国产精品国产一区二区| 日韩亚洲欧美一区| 欧美福利视频| 亚洲国产高清一区| 欧美1区3d| 最新中文字幕一区二区三区| 另类成人小视频在线| 亚洲成色www8888| 在线播放一区| 欧美金8天国| 一本一本久久a久久精品牛牛影视| 欧美精品二区| 亚洲天堂网站在线观看视频| 国产精品视频福利| 欧美在线视频观看免费网站| 国产主播一区二区三区| 久久久午夜电影| 亚洲激情视频在线播放| 欧美日韩亚洲综合一区| 亚洲性视频网址| 国产一区二区三区在线播放免费观看| 久久久欧美精品sm网站| 最新亚洲视频| 国产精品国产亚洲精品看不卡15 | 久久亚洲综合色一区二区三区| 樱桃国产成人精品视频| 欧美精品一区二区三区四区| 这里只有精品在线播放| 国产亚洲欧洲| 欧美精彩视频一区二区三区| 亚洲欧美日韩久久精品| 亚洲国产一区二区精品专区| 国产精品www| 免费久久99精品国产自| 亚洲综合日韩中文字幕v在线| 黑人巨大精品欧美黑白配亚洲| 欧美夫妇交换俱乐部在线观看| 亚洲午夜在线观看视频在线| 一区精品在线播放| 国产精品第一区| 欧美jjzz| 久久不射网站| 一区二区三区四区五区精品视频| 国产专区欧美专区| 国产精品系列在线播放| 欧美日韩免费看|