您現在的位置是:網站首頁> 內容頁

ThreadLocal原理

  • 亞搏官方app
  • 2019-07-09
  • 355人已閱讀
簡介1.?ThreadLocal是什么ThreadLocal提供線程局部變量。這些變量與普通的變量不同之處在于,每個訪問這種變量的線程(通過它的get或set方法)都有自己的、獨立初始化

1.? ThreadLocal是什么

ThreadLocal提供線程局部變量。這些變量與普通的變量不同之處在于,每個訪問這種變量的線程(通過它的get或set方法)都有自己的、獨立初始化的變量副本。

ThreadLocal實例通常是希望將狀態關聯到一個線程的類的私有靜態字段(比如,user ID 或者 Transaction ID 等等)。

畫外音:這段話表達了三個意思

    ThreadLocal是一種變量類型,我們稱之為“線程局部變量”每個線程訪問這種變量的時候都會創建該變量的副本,這個變量副本為線程私有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

?

文章評論

Top 华东六省15选五今天开奖结果 重庆福彩欢乐生肖走势图 中国职业篮球即时比分 1月15日快船vs湖人 球探比分即时足球比分app 苹果 2014太原站街女信息 西安按摩服务 赢策配资 时时彩 3d开奖号试机号 日本av大片快播观看 台湾麻将怎么算胡牌 加勒比赤月美井 竞彩足球比分直播新浪 点玩南京麻将下载 基金配资业务 江苏快三