ThreadLocal 爲了解決多線程併發提供了一種新的思路,ThreadLocal 爲每一個變量維護一個線程的副本,每一個線程能夠獨立的修改副本,不會影響到其餘線程。使用 ThreadLocal 可能須要注意引用的釋放,若是忘記釋放可能會致使對象釋放不了。
ThreadLocal 寫數據過程:java
ThreadLocal 讀數據過程:多線程
總的來講,ThreadLocal 將數據存儲在當前線程的 Thread.threadLocals 這個 ThreadLocalMap 中,並且只有當前線程才能得到這個變量,因此 ThreadLocal 不存在併發問題。
ThreadLocal 結構:併發
public class ThreadLocal<T> { private final int threadLocalHashCode = nextHashCode(); private static AtomicInteger nextHashCode = new AtomicInteger(); private static final int HASH_INCREMENT = 1640531527; public T get() { // 獲取當前線程,並拿到 threadLocals Thread var1 = Thread.currentThread(); ThreadLocal.ThreadLocalMap var2 = this.getMap(var1); if(var2 != null) { // 經過 this 拿到存在當前線程 threadLocals 中的對象 ThreadLocal.ThreadLocalMap.Entry var3 = var2.getEntry(this); if(var3 != null) { Object var4 = var3.value; return var4; } } return this.setInitialValue(); } private T setInitialValue() { Object var1 = this.initialValue(); Thread var2 = Thread.currentThread(); ThreadLocal.ThreadLocalMap var3 = this.getMap(var2); if(var3 != null) { var3.set(this, var1); } else { this.createMap(var2, var1); } return var1; } public void set(T var1) { // 獲取當前線程,並拿到 threadLocals Thread var2 = Thread.currentThread(); ThreadLocal.ThreadLocalMap var3 = this.getMap(var2); if(var3 != null) { // 若是 map 不爲空,經過 this 將對象存到當前線程 threadLocals 中 var3.set(this, var1); } else { // 若是 map 爲空,則建立新的 map,並將對象存到 threadLocals 中 this.createMap(var2, var1); } } public void remove() { ThreadLocal.ThreadLocalMap var1 = this.getMap(Thread.currentThread()); if(var1 != null) { var1.remove(this); } } // 獲取線程的 threadLocals 變量 ThreadLocal.ThreadLocalMap getMap(Thread var1) { return var1.threadLocals; } void createMap(Thread var1, T var2) { var1.threadLocals = new ThreadLocal.ThreadLocalMap(this, var2); } }