ThreadLocal的適用場景

摘抄自https://www.cnblogs.com/coderxx/p/12043764.html

ThreadLoal 變量,它的基本原理是,同一個 ThreadLocal 所包含的對象(對ThreadLocal< StringBuilder >而言即為 StringBuilder 類型變量),在不同的 Thread 中有不同的副本(實際上是不同的實例):

因為每個 Thread 內(nèi)有自己的實例副本,且該副本只能由當前 Thread 使用;
既然其它 Thread 不可訪問,那就不存在多線程間共享的問題。

ThreadLocal 提供了線程本地的實例。它與普通變量的區(qū)別在于,每個使用該變量的線程都會初始化一個完全獨立的實例副本。ThreadLocal 變量通常被private static修飾。當一個線程結(jié)束時,它所使用的所有 ThreadLocal 相對的實例副本都會被回收。

因此ThreadLocal 非常適用于這樣的場景:每個線程需要自己獨立的實例且該實例需要在多個方法中使用。

ThreadLocalMap與內(nèi)存泄漏

在該方案中,Map 由 ThreadLocal 類的靜態(tài)內(nèi)部類 ThreadLocalMap 提供。該類的實例維護某個 ThreadLocal 與具體實例的映射。與 HashMap 不同的是,ThreadLocalMap 的每個 Entry 都是一個對 Key 的弱引用,這一點我們可以從super(k)可看出。另外,每個 Entry 中都包含了一個對 Value 的強引用。

static class Entry extends WeakReference<ThreadLocal<?>> {
  /** The value associated with this ThreadLocal. */
  Object value;

  Entry(ThreadLocal<?> k, Object v) {
    super(k);
    value = v;
  }
}

之所以使用弱引用,是因為當沒有強引用指向 ThreadLocal 變量時,這個變量就可以被回收,就避免ThreadLocal 因為不能被回收而造成的內(nèi)存泄漏的問題。

但是,這里又可能出現(xiàn)另外一種內(nèi)存泄漏的問題。ThreadLocalMap 維護 (key)ThreadLocal 變量與(value)具體實例的映射,當 ThreadLocal 變量被回收后,該映射的鍵變?yōu)?null,該 Entry 無法被移除。從而使得實例被該 Entry 引用而無法被回收造成內(nèi)存泄漏。

注意:Entry是對 ThreadLocal 類型的弱引用,并不是具體實例的弱引用,因此還存在具體實例相關(guān)的內(nèi)存泄漏的問題。

防止內(nèi)存泄漏

對于已經(jīng)不再被使用且已被回收的 ThreadLocal 對象,它在每個線程內(nèi)對應(yīng)的實例由于被線程的 ThreadLocalMap 的 Entry 強引用,無法被回收,可能會造成內(nèi)存泄漏。

針對該問題,ThreadLocalMap 的 set 方法中,通過 replaceStaleEntry 方法將所有鍵為 null 的 Entry 的值設(shè)置為 null,從而使得該值可被回收。另外,會在 rehash 方法中通過 expungeStaleEntry 方法將鍵和值為 null 的 Entry 設(shè)置為 null 從而使得該 Entry 可被回收。

總結(jié)

ThreadLocal 并不解決線程間共享數(shù)據(jù)的問題
ThreadLocal 通過隱式的在不同線程內(nèi)創(chuàng)建獨立實例副本避免了實例線程安全的問題
每個線程持有一個 Map 并維護了 ThreadLocal 對象與具體實例的映射,該 Map 由于只被持有它的線程訪問,故不存在線程安全以及鎖的問題
ThreadLocalMap 的 Entry 對 ThreadLocal 的引用為弱引用,避免了 ThreadLocal 對象無法被回收的問題
ThreadLocalMap 的 set 方法通過調(diào)用 replaceStaleEntry 方法回收鍵為 null 的 Entry 對象的值(即為具體實例)以及 Entry 對象本身從而防止內(nèi)存泄漏
ThreadLocal 適用于變量在線程間隔離且在方法間共享的場景

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容