ThreadLocal原始碼解析

2022-07-07 03:36:09 字數 3142 閱讀 4453

在多執行緒的情況下,threadlocal提供了乙個種為每個執行緒訪問相同的變數,並且執行緒對變數的更新互不影響的機制。也是物件實現執行緒安全的一種方式。

我們常用的方法有getsetinitialvalue,這次將會圍繞這幾個方法的原始碼進行深入解析

//  獲取元素

public t get()

}// 返回initialvalue的值

return setinitialvalue();

}

首先,通過當前執行緒物件獲取threadlocalmap物件,然後以threadlocal物件自身為key獲取threadlocalmap.entry,最後在獲取entry中的value**的邏輯非常簡單,我們再來看看getmapmap.getentry方法

getmap方法

threadlocalmap getmap(thread t)
threadlocals是thread的乙個屬性

public class thread implements runnable
map.getentry方法

threadlocalmapthreadlocal物件的乙個內部類,entrythreadlocalmap的乙個內部類

//  threadlocal的內部類

static class threadlocalmap

}// entry陣列,用來存放乙個執行緒的多個threadlocal變數

private entry table;

// 根據threadlocal來獲取對應的value

private entry getentry(threadlocal> key)

}

key過期了如何獲取值

private entry getentryaftermiss(threadlocal> key, int i, entry e) 

return null;

}

public void set(t value)
先獲取threadlocalmap物件,然後在以threadlocalkey,將value設定到threadlocalmap物件中

map.set方法

//  將threadlocal對應的value儲存到threadlocalmap物件中

private void set(threadlocal> key, object value)

// 去掉過期的threadlocal物件

if (k == null)

}// entry陣列中不存在threadlocal物件,建立乙個新的entry物件

tab[i] = new entry(key, value);

int sz = ++size;

// 清除過期的物件

if (!cleansomeslots(i, sz) && sz >= threshold)

// entry陣列的大小改變以後重新計算hash

rehash();

}

createmap方法

void createmap(thread t, t firstvalue)
// 可以通過重寫該方法來返回預設值

protected t initialvalue()

首先看一下threadlocal中物件的引用關係圖

從threadlocal中物件的引用關係來看,threadthreadlocalmapentry物件之間都是強引用,如果可能出現記憶體洩漏那就是threadlocal物件弱引用引起的。

什麼時候會發生記憶體洩漏

threadlocal例項不在有強引用指向,只有弱引用存在,且gc**了這部分空間時,也就是entry物件中的key被**了,但是value還沒有被**,這時會出現記憶體洩漏,因為value無法得到釋放。

如何避免記憶體洩漏

threadlocalmap中是通過expungestaleentrykeynull的物件對應的value也設定為null

private int expungestaleentry(int staleslot)  else }}

return i;

}

所以只要呼叫expungestaleentry方法,且keynull時就可以**掉value了,我們可以通過呼叫threadlocalremove方法進行釋放

避免threadlocal出現記憶體洩漏的方式有

呼叫threadlocalremove方法

threadlocal變數定義成static型別的,對threadlocal的強引用不會消失,所以也不存在記憶體洩漏的問題,但是可能會有所浪費

ThreadLocal原始碼理解

threadlocal其實原理是建立了多份相同資料儲存在堆記憶體上,每個執行緒的thread類裡有threadlocal.threadlocalmap threadlocals的屬性來指向存位置,所以每個執行緒修改都不會影響到其他執行緒的資料 首先說下下面用到的東西 threadlocalmap為t...

ThreadLocal原始碼分析

在理解handler looper之前,先來說說threadlocal這個類,聽名字好像是乙個本地執行緒的意思,實際上它並不是乙個thread,而是提供乙個與執行緒有關的區域性變數功能,每個執行緒之間的資料互不影響。我們知道使用handler的時候,每個執行緒都需要有乙個looper物件,那麼and...

ThreadLocal 原始碼解讀

在正式讀 前先簡單介紹threadlocal的實現方式。每個執行緒都會有乙個threadlocalmap,只有在使用到threadlocal的時候才會初始化threadlocalmap。需要儲存的物件t會被放到entry裡面儲存在threadlocalmap的陣列中,entry是乙個鍵值對的資料結構...