ThreadLocal
創建一個ThreadLocal,每個執行緒都會復制一個變數到本地記憶體,

簡單使用
class ThreadLocalTest{
static ThreadLocal<String> threadSign = new ThreadLocal<>();
ThreadLocalTest(){
}
public static void setThreadSign(String sign) {
threadSign.set(sign);
System.out.println("設定執行緒"+Thread.currentThread().getName()+"sign為"+threadSign.get());
} public static void removeThreadSign() {
threadSign.remove();
System.out.println("移除執行緒"+Thread.currentThread().getName()+"的sign"+threadSign.get());
}
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
ThreadLocalTest.setThreadSign("我是sign1");
ThreadLocalTest.removeThreadSign();
}
},"AAA").start();new Thread(new Runnable() {
@Override
public void run() {
ThreadLocalTest.setThreadSign("我是sign2");
ThreadLocalTest.removeThreadSign();
}
},"BBB").start();
}
}
實作原理
Thread 類中有 一個threadLocals和一個 inheritableThreadLocals
都是ThreadLocalMap 型別變數,而ThreadLocalMap 是一個定制化的
Hashmap,每個執行緒中他們初始都是null,第一次呼叫set或者get的時候才會創建他們,每個執行緒的本地變數存放在呼叫執行緒的threadLocals變數里,而不是ThreadLocal實體中,ThreadLocal相當于工具殼,如果執行緒一直不終止,那么變數就會一直存放在呼叫執行緒的threadLocals變數中,remove可以洗掉,
Thead里面的threadLocals為何被設定為map結構?
因為每個執行緒可以關聯多個threadLocal變數
set原始碼:
public void set(T value) {
Thread t = Thread.currentThread();
//得到當前執行緒的成員變數threadLocals
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
//獲取當前執行緒的成員變數threadLocals
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
//第一次設定則map==null,先要創建
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
get方法類似:
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
//初始化成員變數
return setInitialValue();
}
private T setInitialValue() {
T value = initialValue();
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}
protected T initialValue() {
return null;
}

如果執行緒不消亡,那么這些本地變數會一直存在,可能造成記憶體溢位,因此最好呼叫remove洗掉,其中key為ThreadLocal變數的this參考,
ThreadLocal的不支持繼承性
父類設定的threadLocal變數,在子執行緒是無法獲取的
如何讓子類訪問父執行緒的值?
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/279245.html
標籤:java
