這篇文章帶給大家的內容是關於ThreadLocal是什麼? ThreadLocal的原理分析,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。
1、 ThreadLocal是什麼
ThreadLocal提供執行緒局部變數。這些變數與普通的變數不同之處在於,每個存取這種變數的執行緒(透過它的get或set方法)都有自己的、獨立初始化的變數副本。
ThreadLocal實例通常是希望將狀態關聯到一個執行緒的類別的私人靜態欄位(例如,user ID 或 Transaction ID 等等)。
(畫外音:這段話表達了三個意思
1、ThreadLocal是一種變數類型,我們稱之為「線程局部變數」。
2、每個執行緒存取這種變數的時候都會建立該變數的副本,這個變數副本為線程私有。
3、ThreadLocal類型的變數一般用private static加以修飾。)
例如,下面的例子中這個類別為每個執行緒產生唯一標識。一個執行緒的id是它第一次呼叫ThreadId.get()方法指定的。
package com.cjs.example; import java.util.concurrent.atomic.AtomicInteger; public class ThreadId { private static final AtomicInteger nextId = new AtomicInteger(0); private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return nextId.getAndIncrement(); } }; public static int get() { return threadId.get(); } public static void main(String[] args) { for (int i = 0; i < 10; i++) { new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getId()); } }).start(); } } }
2. ThreadLocal主要動作
/** * 返回当前线程对ThreadLocal变量的“初始值” * 这个方法将在线程第一次访问变量(通过调用get方法)时被调用,如果之前已经调用过了就不会再调了 * * @return the initial value for this thread-local */ protected T initialValue() { return null; } /** * 设置当前线程的ThreadLocal变量的副本为指定的值 * * @param value the value to be stored in the current thread's copy of this thread-local. */ public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } /** * 返回当前线程的ThreadLocal变量副本的值 * * @return the current thread's value of this thread-local */ public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); } /** * 删除当前线程的ThreadLocal变量副本的值 */ public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); }
3. 閱讀原始碼
3.1. set方法
可以看到,ThreadLocalMap底層是一個數組,數組中元素類型是Entry類型
set操作是向當前線程的ThreadLocal.ThreadLocalMap類型的成員變數threadLocals中設定值,key是this,value是我們指定的值
注意,這裡傳的this代表的是那個ThreadLocal類型的變數(或者說叫做對象)
也就是說,每個執行緒都維護了一個ThreadLocal.ThreadLocalMap類型的對象,而set操作其實就是以ThreadLocal變數為key,以我們指定的值為value,最後將這個鍵值對封裝成Entry物件放到該執行緒的ThreadLocal.ThreadLocalMap物件中。每個ThreadLocal變數在該執行緒中都是ThreadLocal.ThreadLocalMap物件中的一個Entry。既然每個ThreadLocal變數都對應ThreadLocal.ThreadLocalMap中的一個元素,那麼就可以對這些元素進行讀寫刪除操作。
3.2. get方法
get()方法是從目前執行緒的ThreadLocal.ThreadLocalMap物件中取出對應的ThreadLocal變量所對應的值
同理,remove()方法就是清除這個值
用圖形表示的話,大概是這樣的:
或是這樣的:
4. ThreadLocal使用場景
在執行緒生命週期內傳值
最後,一切都歸功於ThreadLocalMap
以上是ThreadLocal是什麼? ThreadLocal的原理分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!