1. 程式人生 > 實用技巧 >Adobe出品的專門為Web開發者設計的跨平臺開源編輯器Brackets

Adobe出品的專門為Web開發者設計的跨平臺開源編輯器Brackets

1,ThreadLocal是什麼:

ThreadLocal也是解決多執行緒訪問共享變數問題的,不同於加鎖,他會在每一個執行緒內部建立副本,

每個執行緒獨立訪問自己內部的副本,不會產生衝突。

2,用法:

示例:

  public class ThreadLocalTest {
  
      static ThreadLocal<String> localVar = new ThreadLocal<>();
  
      static void print(String str) {
          //列印當前執行緒中本地記憶體中本地變數的值
          System.out.println(str + " :" + localVar.get());
         
//清除本地記憶體中的本地變數 localVar.remove(); } public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { //設定執行緒1中本地變數的值 localVar.set("localVar1"); //呼叫列印方法
print("thread1"); //列印本地變數 System.out.println("after remove : " + localVar.get()); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { //設定執行緒1中本地變數的值 localVar.set("localVar2");
//呼叫列印方法 print("thread2"); //列印本地變數 System.out.println("after remove : " + localVar.get()); } }); t1.start(); t2.start(); } }
View Code

3,原理:

ThreadLocal類:

①內部類:ThreadLocalMap

是一個雜湊表,迴圈陣列+開發地址法中線性探測法解決雜湊衝突。

什麼意思呢?試試想一下:線性探測法會在陣列中形成以null隔開的若干‘塊’,我們把它類比成拉鍊法裡面的每一個連結串列。

線性探測法在一個快中(快可能未null)新增元素就相當於尾插法,刪除元素,就要調整該快中,被刪除元素之後的元素,要前移

保證他們下次能被探測到。就緒拉鍊法裡面的調整指標關係。

Entry陣列儲存的是key-value鍵值對,key是ThreadLocal,value是Object物件。

  • 引數:

  • 方法:主要是雜湊表的,增刪改查

①增刪改查之前,首先要介紹一下expungeStaleEntry()函式,顧名思義刪除元素用的

②getEntry():

getEntryAfterMiss():

③set()函式:

replaceStaleEntry()

cleanSomeSlots();

④remove()

⑤rehash()

expungeStaleEntries()

resize()擴容:

總結:ThreadLocalMap(),雜湊表,陣列+線性探測法解決雜湊衝突。初始容量16,擴容*2.

在增刪改查中不停清理,失效的TreadLocal元素。

記憶體洩漏問題:

<1>ThreadLocalMap的Entry陣列是key為ThreadLocal的弱引用,而valve是強引用。如果ThreadLocal物件沒有被外部強引用,垃圾回收時,key被回收

為null但是value還在。造成記憶體洩漏。

<2>雖然ThreadLocalMap在get(),set()函式裡多次清理key為null的失效元素,但是當沒有呼叫get(),set()時,不會清理。

解決方法:<1>使用完ThreadLocal後手動呼叫remove方法。

<2>將ThreadLocal定義為private static 隨執行緒一起消亡。

②看完ThreadLocalMap,在回到ThreadLocal類,

  • set()

  • get()

map空就初始化map

  • 雖然ThreadLocalMap是ThreadLocal內部類,但ThreadLocal裡並沒有ThreadLocalMap引數,

而是通過getMap()方法;獲得執行緒的threadlocalS。

呼叫getMap的地方也是傳入當前執行緒的

進入Thread類:

ThreadLocalMap例項化在Thread類裡作為引數。即每一個執行緒有一個,哈西表,threadlocals,顧名思義用來存放該

執行緒ThreadLocals變數的。

ThreadLocal是ThreadLocalMap的封裝,提供了set(),get();看起來是每個Threadlocal變數單獨get(),set()。背後還是通過每個Thred的

ThredLocalMap統一管理所有ThreadLocal變數;

參考:

https://www.cnblogs.com/fsmly/p/11020641.html

https://baijiahao.baidu.com/s?id=1653790035315010634&wfr=spider&for=pc

https://www.jianshu.com/p/80866ca6c424

https://blog.csdn.net/ywlmsm1224811/article/details/91388109