成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

你問這誰會?。縏hreadLocal 父子線程之間該如何傳遞數(shù)據(jù)?

開發(fā) 前端
如果你使用 InheritableThreadLocal?,那么保存的數(shù)據(jù)都已經不在原來的 ThreadLocal.ThreadLocalMap threadLocals? 里面了,而是在一個新的 ThreadLocal.ThreadLocalMap inheritableThreadLocals 變量中了。

忘記之前是哪個公司面試的時候問到的,并不是一個常見的問題,我當時也沒回答正確,就按照線程通信那一套比如什么 synchronized、Locks、volatile 啥的 XJB 說的,面試完找了些資料今天整理了下分享給大家~

ThreadLocal 的具體原理這篇文章就不解釋了,能干啥大伙兒都倒背如流,其實就兩點:

  • 鏈路透傳(通俗來說就是方便做參數(shù)傳遞,不用在調用方法時攜帶一堆請求參數(shù))
  • 線程隔離

每個線程都有自己的一個 ThreadLocalMap,ThreadLocal 持有的數(shù)據(jù)就是存在這個 Map 里的(Thread.ThreadLocalMap threadLocals),所以能夠實現(xiàn)線程隔離,畢竟每個線程的 ThreadLocalMap 都是不一樣的

那如果子線程想要拿到父線程的中的 ThreadLocal 值怎么辦呢?

比如會有以下的這種代碼的實現(xiàn)。在子線程中調用 get 時,我們拿到的 Thread 對象是當前子線程對象,對吧,每個線程都有自己獨立的 ThreadLocal,那么當前子線程的 ThreadLocalMap 是 null 的(而父線程,也就是 main 線程中的 ThreadLocalMap 是有數(shù)據(jù)的),所以我們得到的 value 也是 null

public class ThreadLocalTest {
private static ThreadLocal<String> threadLocal = new ThreadLocal<String>();

public static void main(String[] args) throws Exception{
threadLocal.set("飛天小牛肉");
System.out.println("父線程的值:"+ threadLocal.get());
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子線程的值:"+ threadLocal.get());
}
}).start();

Thread.sleep(2000);
}
}

結果輸出如下:

父線程的值:飛天小牛肉
子線程的值:null

要如何解決這個問題呢?

我們先來從 Thread 類中找找思路:

圖片

你會發(fā)現(xiàn),在 ThreadLocalMap threadLocals 的下方,還有一個 ThreadLocalMap 變量 inherittableThreadLocals,inherit 翻譯為繼承

先看下這個變量的注釋:InheritableThreadLocal values pertaining to this thread. This map is maintained by the InheritableThreadLocal class.

oho,這里出現(xiàn)了一個渣渣輝都從未體驗過的傳新類:InheritableThreadLocal

翻譯一下注釋,大概就是,如果你使用 InheritableThreadLocal,那么保存的數(shù)據(jù)都已經不在原來的 ThreadLocal.ThreadLocalMap threadLocals 里面了,而是在一個新的 ThreadLocal.ThreadLocalMap inheritableThreadLocals 變量中了。

圖片

所以,如果想讓上面那段代碼中,子線程能夠拿到父線程的 ThreadLocal 值,只需要把 ThreadLocal 聲明改為 InheritableThreadLocal 就可以了

下面我們具體來看下 InheritableThreadLocal 是怎么做到父子線程傳值的。

首先看下 new Thread 的時候線程都做了些什么 Thread#init()

private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc){
// 省略部分代碼
Thread parent = currentThread();

if (inheritThreadLocals && parent.inheritableThreadLocals != null)
// copy父線程的 map,創(chuàng)建一個新的 map 賦值給當前線程的inheritableThreadLocals
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);

// 省略部分代碼
}

核心其實就是上面幾句代碼,如果你設置了 inheritableThreadLocals 變量,那么 Thread 就會把父線程 ThreadLocal threadLocals 中的所有數(shù)據(jù)都 copy 到子線程的 InheritableThreadLocal inheritableThreadLocals 中。

而且,copy 調用的 createInheritedMap 方法其實是一個淺拷貝函數(shù),key 和 value 都是原來的引用地址,這里所謂的 copy 其實就是把一個 Map 中的數(shù)據(jù)復制到另一個 Map 中:

圖片

至此,大致的解釋了 InheritableThreadLocal 為什么能解決父子線程傳遞 Threadlcoal 值的問題了,總結下:

在創(chuàng)建InheritableThreadLocal 對象的時候賦值給線程的 t.inheritableThreadLocals 變量。

在創(chuàng)建新線程的時候會 check 父線程中 t.inheritableThreadLocals 變量是否為 null,如果不為 null 則 copy 一份數(shù)據(jù)到子線程的 t.inheritableThreadLocals 成員變量中去。

InheritableThreadLocal 重寫了 getMap(Thread) 方法,所以 get 的時候,就會從 t.inheritableThreadLocals 中拿到 ThreadLocalMap 對象,從而實現(xiàn)了可以拿到父線程 ThreadLocal 中的值。

責任編輯:武曉燕 來源: 飛天小牛肉
相關推薦

2011-09-07 16:57:31

QT WidgetQWidget

2023-10-07 08:26:40

多線程數(shù)據(jù)傳遞數(shù)據(jù)共享

2024-07-09 08:35:09

2010-03-16 17:16:38

Java多線程

2024-11-25 13:49:00

2015-05-18 15:36:38

大數(shù)據(jù)如何定義大數(shù)據(jù)

2018-11-28 09:53:50

游戲服務器線程

2010-03-01 13:28:44

Python子線程

2021-10-03 15:00:44

數(shù)據(jù)庫mysql單機

2020-12-11 07:32:45

編程ThreadLocalJava

2015-11-02 10:32:43

bat騰訊百度

2017-07-11 18:00:21

vue.js數(shù)據(jù)組件

2021-09-09 18:42:12

React 組件數(shù)據(jù)

2022-05-09 07:27:50

ThreadLocaJava

2017-11-06 16:32:53

PythonC++Java

2024-06-26 19:04:09

線程異步函數(shù)Actix

2022-10-25 10:20:31

線程變量原理

2021-03-28 23:37:35

線程專屬變量

2019-07-05 10:53:55

ReactVue前端

2016-12-29 11:01:54

ReactVue
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩不卡一二区 | 国产一区二区影院 | 久久久久久久久国产 | 欧美a在线 | 欧美一区视频 | 毛片区 | 欧美精品a∨在线观看不卡 欧美日韩中文字幕在线播放 | 蜜桃传媒一区二区 | 日日夜夜天天综合 | 亚洲aⅴ | 一区二区精品 | 日韩精品 电影一区 亚洲 | 欧美精品乱码久久久久久按摩 | 久久精品视频一区二区 | 亚洲第一在线视频 | 精品国产aⅴ | 欧美日韩国产一区二区三区 | 欧美电影网 | 久久久久国产一区二区三区 | 久久国产亚洲 | 日韩欧美手机在线 | 久色视频在线观看 | 狠狠干五月天 | 成人av播放| 亚洲精品2区 | 欧美性大战久久久久久久蜜臀 | 成人精品一区二区三区 | 午夜精品在线观看 | 久久综合一区 | 成人在线精品视频 | 91视频一区| 久久久久久免费毛片精品 | 国产视频91在线 | 高清人人天天夜夜曰狠狠狠狠 | 欧美jizzhd精品欧美巨大免费 | 丁香婷婷综合激情五月色 | 国产激情在线观看视频 | 国产精品久久久久久婷婷天堂 | 亚洲一区 | tube国产| 国产成人综合网 |