亚洲免费在线视频-亚洲啊v-久久免费精品视频-国产精品va-看片地址-成人在线视频网

您的位置:首頁技術文章
文章詳情頁

重新認識Java中的ThreadLocal

瀏覽:6日期:2022-08-11 15:35:30
目錄究竟是啥結構內存泄漏是什么鬼

說來也慚愧,這個 ThreadLocal 其實一直都是一知半解,而且看了一下之后還發(fā)現記錯了,所以還是記錄下原先記憶里的都是反過來,一個 ThreadLocal 是里面按照 thread 作為 key,存儲線程內容的,真的是半解都米有,完全是錯的,這樣就得用 concurrentHashMap 這種去存儲并且要鎖定線程了,然后內容也只能存一個了,想想簡直智障

究竟是啥結構

比如我們在代碼中 new 一個 ThreadLocal,

public static void main(String[] args) {ThreadLocal<Man> tl = new ThreadLocal<>();new Thread(() -> { try {TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {e.printStackTrace(); } System.out.println(tl.get());}).start();new Thread(() -> { try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) {e.printStackTrace(); } tl.set(new Man());}).start(); } static class Man {String name = 'nick'; }

這里構造了兩個線程,一個先往里設值,一個后從里取,運行看下結果,

重新認識Java中的ThreadLocal

知道這個用法的話肯定知道是取不到值的,只是具體的原理原來搞錯了,我們來看下設值 set 方法

public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null)map.set(this, value); elsecreateMap(t, value);}

寫博客這會我才明白我原來咋會錯得這么離譜,看到第一行代碼 t 就是當前線程,然后第二行就是用這個線程去getMap,然后我是把這個當成從 map 里取值了,其實這里是

ThreadLocalMap getMap(Thread t) { return t.threadLocals;}

獲取 t 的 threadLocals 成員變量,那這個 threadLocals 又是啥呢

重新認識Java中的ThreadLocal

它其實是線程 Thread 中的一個類型是java.lang.ThreadLocal.ThreadLocalMap的成員變量這是 ThreadLocal 的一個靜態(tài)成員變量

static class ThreadLocalMap {/** * The entries in this hash map extend WeakReference, using * its main ref field as the key (which is always a * ThreadLocal object). Note that null keys (i.e. entry.get() * == null) mean that the key is no longer referenced, so the * entry can be expunged from table. Such entries are referred to * as 'stale entries' in the code that follows. */static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) {super(k);value = v; }} }

全部代碼有點長,只截取了一小部分,然后我們再回頭來分析前面說的 set 過程,再 copy 下代碼

public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null)map.set(this, value); elsecreateMap(t, value);}

獲取到 map 以后呢,如果 map 不為空,就往 map 里 set,這里注意 key 是啥,其實是當前這個 ThreadLocal,這里就比較明白了究竟是啥結構,每個線程都會維護自身的 ThreadLocalMap,它是線程的一個成員變量,當創(chuàng)建 ThreadLocal 的時候,進行設值的時候其實是往這個 map 里以 ThreadLocal 作為 key,往里設 value。

內存泄漏是什么鬼

這里又要看下前面的 ThreadLocalMap 結構了,類似 HashMap,它有個 Entry 結構,在設置的時候會先包裝成一個 Entry

private void set(ThreadLocal<?> key, Object value) {// We don’t use a fast path as with get() because it is at// least as common to use set() to create new entries as// it is to replace existing ones, in which case, a fast// path would fail more often than not.Entry[] tab = table;int len = tab.length;int i = key.threadLocalHashCode & (len-1);for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal<?> k = e.get(); if (k == key) {e.value = value;return; } if (k == null) {replaceStaleEntry(key, value, i);return; }}tab[i] = new Entry(key, value);int sz = ++size;if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash();}

這里其實比較重要的就是前面的 Entry 的構造方法,Entry 是個 WeakReference 的子類,然后在構造方法里可以看到 key 會被包裝成一個弱引用,這里為什么使用弱引用,其實是方便這個 key 被回收,如果前面的 ThreadLocal tl實例被設置成 null 了,如果這里是直接的強引用的話,就只能等到線程整個回收了,但是其實是弱引用也會有問題,主要是因為這個 value,如果在 ThreadLocal tl 被設置成 null 了,那么其實這個 value 就會沒法被訪問到,所以最好的操作還是在使用完了就 remove 掉

以上就是詳解Java中的ThreadLocal的詳細內容,更多關于Java ThreadLocal的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 中文字幕无线码中文字幕网站 | 久久久久久久久久综合情日本 | 一级欧美过瘾大片 | 黄色片三级网站 | 国产在线精品二区韩国演艺界 | 美女三级在线 | 男女免费视频 | 黄网在线免费 | 国产亚洲一区二区三区 | 精品亚洲欧美高清不卡高清 | 亚洲精品久久99久久一区 | 黄色va视频| 久久99久久 | 国产男女猛烈无遮档免费视频网站 | a级毛片免费观看视频 | 日本一区二区三区在线 视频 | 国产乱码一区二区三区四 | 成年人视频在线免费播放 | 国产乱子伦真实china | 亚洲欧美另类在线视频 | 欧美日韩国产58香蕉在线视频 | 国产精品免费观在线 | 国产精品自在自线 | 欧美精品亚洲一区二区在线播放 | 俄罗斯美女在线观看一区 | 免费一级特黄3大片视频 | 农村寡妇女人一级毛片 | 在线视免费频观看韩国aaa | 亚洲视频在线观看网站 | 亚洲一区 在线播放 | 精品久久成人 | aaa一级毛片| 自拍第一页 | 日韩美女视频在线观看 | 欧美视频xxxxx | 国产精品短视频免费观看 | 日本精品视频一视频高清 | 中文字幕日韩有码 | 一本一本久久a久久精品综合麻豆 | 亚洲精品国产精品精 | 亚洲高清在线观看看片 |