日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

什么时候使用 InheritableThreadLocal

發布時間:2024/1/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 什么时候使用 InheritableThreadLocal 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、ThreadLocal 在父子線程傳遞的問題

public class InheritableThreadLocalDemo {// 全局變量 // static ThreadLocal<String> threadLocal = new ThreadLocal<>();static ThreadLocal<String> threadLocal = new InheritableThreadLocal<>();public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {InheritableThreadLocalDemo.threadLocal.set("superWorld");new Service().call();}}).start();} }class Service {public void call() {System.out.println("Service:" + Thread.currentThread().getName() + " : " + InheritableThreadLocalDemo.threadLocal.get());//new Dao().call();new Thread(new Runnable() {@Overridepublic void run() {new Dao().call();}}).start();} }class Dao {public void call() {System.out.println("Dao:" + Thread.currentThread().getName() + " : " + InheritableThreadLocalDemo.threadLocal.get());}}

?

?

二、InheritableThreadLocal 和?ThreadLocal 的區別

1. InheritableThreadLocal 實現

public class InheritableThreadLocal<T> extends ThreadLocal<T> {/*** Computes the child's initial value for this inheritable thread-local* variable as a function of the parent's value at the time the child* thread is created. This method is called from within the parent* thread before the child is started.* <p>* This method merely returns its input argument, and should be overridden* if a different behavior is desired.** @param parentValue the parent thread's value* @return the child thread's initial value*/protected T childValue(T parentValue) {return parentValue;}/*** Get the map associated with a ThreadLocal.** @param t the current thread*/ThreadLocalMap getMap(Thread t) {return t.inheritableThreadLocals;}/*** Create the map associated with a ThreadLocal.** @param t the current thread* @param firstValue value for the initial entry of the table.*/void createMap(Thread t, T firstValue) {t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);} }

??

2. ThreadLocal 的getMap、createMap實現

/*** Get the map associated with a ThreadLocal. Overridden in* InheritableThreadLocal.** @param t the current thread* @return the map*/ThreadLocalMap getMap(Thread t) {return t.threadLocals;}/*** Create the map associated with a ThreadLocal. Overridden in* InheritableThreadLocal.** @param t the current thread* @param firstValue value for the initial entry of the map*/void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);}

?

通過上面的代碼我們可以看到InheritableThreadLocal 重寫了childValue, getMap,createMap三個方法,

當我們往里面set值的時候,值保存到了inheritableThreadLocals里面,而不是之前的threadLocals。

?

三、問題:為什么當創建子線程時,可以獲取到上個線程里的threadLocal中的值呢?

原因就是在新創建線程的時候,會把之前線程的inheritableThreadLocals賦值給新線程的inheritableThreadLocals,通過這種方式實現了數據的傳遞。

代碼關鍵點:

1. Thread#init

if (parent.inheritableThreadLocals != null)this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);

?

?

2.?ThreadLocal.createInheritedMap

  static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {return new ThreadLocalMap(parentMap);}private ThreadLocalMap(ThreadLocalMap parentMap) {Entry[] parentTable = parentMap.table;int len = parentTable.length;setThreshold(len);table = new Entry[len];for (int j = 0; j < len; j++) {Entry e = parentTable[j];if (e != null) {@SuppressWarnings("unchecked")ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();if (key != null) {Object value = key.childValue(e.value);Entry c = new Entry(key, value);int h = key.threadLocalHashCode & (len - 1);while (table[h] != null)h = nextIndex(h, len);table[h] = c;size++;}}}}

?

總結

以上是生活随笔為你收集整理的什么时候使用 InheritableThreadLocal的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。