threadlocal,可以叫做執行緒本地變數或執行緒本地儲存,顧名思義就是threadlocal為變數在每個執行緒中都建立了乙個副本,那麼每個執行緒可以訪問自己內部的副本變數。其實就是通過空間換時間的方式來取得對每個執行緒各自變數的共享。
變數值的共享可以使用 public static 變數的形式,所有的執行緒都使用同乙個被 public static 修飾的變數。threadlocal主要解決的就是每個執行緒繫結自己的值,可以將threadlocal模擬喻成全 局存放資料的盒子,盒子中可以儲存每個執行緒的私有變數。
到這裡基本就可以看出threadlocal是如何為每個執行緒建立變數的副本的:
首先,在每個執行緒thread內部有乙個threadlocal.threadlocalmap型別的成員變數threadlocals,這個threadlocals就是用來儲存實際的變數副本的,key為當前threadlocal變數,value為變數副本(即t型別的變數)。
初始時,在thread裡面,threadlocals為空,當通過threadlocal變數呼叫get()方法或者set()方法,就會對thread類中的threadlocals進行初始化,並且以當前threadlocal變數為鍵值,以threadlocal要儲存的副本變數為value,存到threadlocals。
然後在當前執行緒裡面,如果要使用副本變數,就可以通過get方法在threadlocals裡面查詢。
public class test
public long getlong()
public string getstring()
public static void main(string args) throws interruptedexception ;
};thread1.start();
thread1.join();
system.out.println(test.getlong());
system.out.println(test.getstring());}}
這段**的輸出結果為:
從執行結果看出:因為例項化了兩個threadlocal變數,所以他們對各自的區域性變數儲存的副本值是不一樣的,因此在兩個執行緒中的執行並不會互相影響各自的變數值。
總結一下:
1)實際的通過threadlocal建立的副本是儲存在每個執行緒自己的threadlocals中的;
2)為何threadlocals的型別threadlocalmap的鍵值為threadlocal物件,因為每個執行緒中可有多個threadlocal變數,就像上面**中的longlocal和stringlocal;
3)在進行get之前,必須先set,否則會報空指標異常;
如果想在get之前不需要呼叫set就能正常訪問的話,必須重寫initialvalue()方法,設定預設值。
因為在上面的**分析過程中,我們發現如果沒有先set的話,即在map中查詢不到對應的儲存,則會通過呼叫setinitialvalue方法返回i,而在setinitialvalue方法中,有乙個語句是t value = initialvalue(), 而預設情況下,initialvalue方法返回的是null。
使用inheritablethreadlocal類可以實現值的繼承,讓子執行緒從父執行緒中取得值。不過要注意,如果子執行緒在取得值的同時,父執行緒將inheritablethreadlocal中的值進行修改,那麼子執行緒取到的還是原來的值。
ThreadLocal原理探尋
筆者今天趁著專案空隙,學習了下threadlocal這個類,探尋了下多執行緒下如何實現執行緒安全的原理。分享下 package com.suning.sample.transcation public class threadtest public static void main string a...
ThreadLocal原理詳解
threadlocal稱為執行緒本地變數,其為變數在每個執行緒中都建立了乙個副本,每個執行緒都訪問和修改本執行緒中變數的副本。應用示例 可以看出,為每個執行緒分配乙個變數副本的工作並不是由threadlocal實現的,需要在應用層面實現,threadlocal只是提供乙個容器。如果在應用上為每個執行...
ThreadLocal實現原理
threadlocal,即執行緒區域性變數,其實就是乙個容器,每個執行緒都可通過其set方法儲存乙份資料,並且在get時只會獲取自己執行緒的資料,是常用的實現執行緒安全的方式。自己用過許多次了,但沒有細究其原理,今天大概看了一下原始碼,算是明白了一點點0.0 直接看threadlocal的get方法...