1. 程式人生 > 實用技巧 >Java - 【ThreadLocal】執行緒本地變數

Java - 【ThreadLocal】執行緒本地變數

ThreadLocal

  • ThreadLocal是什麼?是用來幹什麼的?
  • ThreadLocal和Thread有什麼關係?
  • Thread底層是如何實現的(底層原理是什麼)?
  • [過渡] → 為什麼Entry要繼承於Weakness?
  • [過渡] → 為什麼ThreadLocal要提供remove()方法?
  • ThreadLocal會造成記憶體洩漏,你瞭解嗎?
  • 什麼是記憶體洩漏?
  • 舉幾個Java中記憶體洩漏的例子

一:ThreadLocal是什麼?是用來幹什麼的?

ThreadLocal全稱執行緒本地變數,ThreadLocal可以使得每個執行緒操作屬於自己的TL不是共享TL
在這裡插入圖片描述

二:ThreadLocal和Thread有什麼關係?

ThreadLocal的set方法與get方法通過操作Thread類中的threadLocals(ThreadLocal.ThreadLocalMap)成員實現;

在這裡插入圖片描述在這裡插入圖片描述

三:ThreadLocal底層是如何實現的?

ThreadLocal物件提供了三個主要的方法:

  • set(T value)
  • get()
  • remove()

1> set(T value) + get( )
在這裡插入圖片描述
接下來檢視ThreadLocalMap是什麼:
在這裡插入圖片描述現在抽象出set()、get()方法的執行邏輯:

在這裡插入圖片描述

2> remove()

移除ThreadLocal在當前執行緒內的Entry
在這裡插入圖片描述在這裡插入圖片描述

四:ThreadLocal會造成記憶體洩漏,你瞭解嗎?

  • 為什麼Entry要繼承於Weakness?
    • 如果全域性變數ThreadLocal tl = null,那麼記憶體中的ThreadLocal由於有Entry中的key一直指向,將會永遠不會被垃圾回收;
    • 為了防止這種情況導致的記憶體洩漏,將Entry繼承於Weakness,Entry中的key值使用Weakness的建構函式初始化;
  • 為什麼ThreadLocal另一個會因為程式設計師操作不當實際存在的記憶體洩漏在什麼地方?
    • 上方Entry中的key是虛引用型別,但是Entry的value不是虛引用,value所指向的物件仍然有可能會造成記憶體洩漏;
    • 所以ThreadLocal提供了remove方法用於手動清除整個Entry。

五:什麼是記憶體洩漏?還在哪些地方能夠體現?

  • 記憶體洩漏(MemoryLeak):部分物件不再使用,但是因為某些原因不能被GC回收,一直佔用記憶體的現象;
  • 其他案例finalize的使用不當