亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中的線程ThreadLocal詳細解析

 更新時間:2023年10月26日 09:04:32   作者:buzhbuzh  
這篇文章主要介紹了Java中的線程ThreadLocal詳細解析,ThreadLocal是線程本地變量,存儲在ThreadLocal里面的數(shù)據都是線程安全的,一般ThreadLocal適用的場景多是各個線程間沒有變量共享需要的同步問題場景,需要的朋友可以參考下

一 Java中的引用關系

Java中的引用分為了強引用、弱引用、軟引用、虛引用

  • 強引用: 垃圾回收的時候,如果內存不足也不會進行垃圾回收,會報out-of-memory異常
  • 弱引用: 垃圾回收的時候,如果內存不夠,則數(shù)據被回收.
  • 軟引用: 垃圾回收的時候,軟引用會立刻進行回收
  • 虛引用: 垃圾回收的時候,軟引用會立刻進行回收

二 ThreadLocal代碼實現(xiàn)

ThreadLocal是線程本地變量,存儲在ThreadLocal里面的數(shù)據都是 線程安全的.

一般ThreadLocal適用的場景多是各個線程間沒有變量共享需要的同步問題場景,比如一個簡單的SimpleDateFormat類,該類不是線程安全的,卻是有狀態(tài)的,如果將SimpleDateFormat設置為靜態(tài)的,所有線程共享,那么就會出現(xiàn)線程安全的問題,其中一個線程修改日期格式為“yyyyMMdd”,然后可能會影響到另外一個需要格式為“yyyy-MM-dd”的線程。但是如果在方法中每次用到的時候都new一個SimpleDateFormat類又太費內存(SimpleDateFormat這種簡單的類倒還好,若是一些比較占用資源的比如數(shù)據庫連接類等,就會讓加大整個數(shù)據庫的壓力),這時候采用ThreadLocal為每一個線程保存一份SimpleDateFormat副本,這樣既不會說每次調用方法都會生成一個對象,也不會在并發(fā)時產生線程同步問題。這就像是在共享一個靜態(tài)變量和每次使用都new一個對象兩者之間的一種折中處理方法。

自己實現(xiàn)的ThreadLocal

在這里插入圖片描述

通過一個全局map, key是Thread對象,value是對應存儲的數(shù)據,這種情況下 如果map不銷毀,對應的Thread線程就不發(fā)被回收,導致內存泄露

JDK中使用的ThreadLocal

在這里插入圖片描述

JDK8中在Thread對象中引用ThreadLocalMap,ThreadLocalMap的生命周期是Thread是同一個生命周期.

ThreadLocalMap的實現(xiàn)

(1) Entry數(shù)組實現(xiàn)

在這里插入圖片描述

Entry數(shù)組是線程中實際存放數(shù)據的地方,key是ThreadLocal,是一個弱引用,value是對應存儲的值.

為什么ThreadLocalMap#key是一個弱引用

如果外部不使用了ThreadLocal,則對應的數(shù)據不應該存儲在ThreadLocal中,應該被刪除掉,防止內存泄漏

ThreadLocalMap的屬性

        private static final int INITIAL_CAPACITY = 16;
    	//存儲數(shù)據的地方
        private Entry[] table; //
    	//數(shù)量
        private int size = 0;
        private int threshold; // Default to 0

ThreadLocal的方法

ThreadLocal#set()方法

在這里插數(shù)據入圖片描述

(1) 第一步 獲取到當前線程的ThreadLocalMap

(2) 第二步 初始化ThreadLocalMap

(3) 第三步 將ThreadLocal作為key,value值作為值,設置到map中

ThreadLocal # get()方法

在這里插入圖片描述

方法主要完成兩個功能: (1) 完成數(shù)據的讀取 (2) 將ThreadLocalMap中key為NULL的數(shù)據從ThreadLocalMap中刪除

ThreadLocalMap中的entry其實是繼承的弱引用,如果該弱引用指向的ThreadLocal沒有在外部被強引用指向的話,在下次gc的時候就會被回收,那這樣的話就會出現(xiàn)ThreadLocalMap中存在key為null的情況,這樣的數(shù)據對于map來講是臟數(shù)據,這樣的臟數(shù)據沒有用,卻一直占用著map的存儲空間,這其實就是一種內存泄漏,所以需要來釋放掉這些空間

三 ThreadLocalMap的內存泄漏問題

如果ThreadLocal無強引用進行應用,則在垃圾回收的時候會把這個key進行回收.

這個時候,因為線程還存活,所以ThreadLocalMap依舊存在,但是key為null,這個 key對應的value就無法被訪問到了,造成內存泄漏.

JDK團隊自己的解決辦法

調用get()、set()方法的時候,自動清理掉ThreadLocalMap中key為null的數(shù)據

開發(fā)者的解決辦法 使用ThreadLocal后,調用ThreadLocal

到此這篇關于Java中的線程ThreadLocal詳細解析的文章就介紹到這了,更多相關Java的ThreadLocal內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論