ThreadLocal 其實應該叫作ThreadLocalVariable。即線程局部變量。web
程序中的變量在多線程狀況下,是由多個線程共享的,這樣很容易出現問題。例如,若多個線程共享數據庫鏈接,線程1將線程2的數據庫鏈接關閉,則線程2在使用數據庫鏈接時就會拋出異常。數據庫
如果每一個線程都可以有本身的單獨的變量,就不會再擔憂出現這樣的問題了。這就是ThreadLocal要作的事。多線程
ThreadLocal爲每個線程提供了一個獨立的變量副本,每個線程均可以獨立的改變本身的副本而不會影響其餘線程的副本。併發
ThreadLocal實現原理spa
在ThreadLocal內部有一個Map,用於存儲每個線程的變量副本。Map中元素的鍵爲線程對象,值爲線程對象的變量副本。線程
本身實現一下ThreadLocal:orm
public class ThreadLocal<T> {對象
private Map<Thread, T> container = Collections.synchronizedMap(new HashMap<Thread, T>());rem
public void set(T value){get
container.put(Thread.currentThread(), value);
}
public T get(){
Thread thread = Thread.currentThread();
T value = container.get(thread);
if(value == null && !container.containsKey(thread)){
value = initialValue();
container.put(thread, value);
}
return value;
}
public void remove(){
container.remove(Thread.currentThread());
}
protected T initialValue(){
return null;
}
}
ThreadLocal和線程同步機制的比較
相同點:都是爲了解決多線程下變量的訪問衝突問題。
不一樣點:在線程同步機制中,經過對象的鎖機制來確保同一時間只有一個線程來訪問此變量。該變量是由多個線程共享的。而ThreadLocal則是爲每個線程提供一個獨立的變量副本,從而也不必對此變量進行同步了。同步機制採用「以時間換空間」的方法,讓每一個線程排隊等待;而ThreadLocal則採起了「以空間換時間」的方法,爲每個線程提供了獨立副本。
ThreadLocal比同步機制更方便,具備更高的併發性。