一句話總結
將T value存到當前線程的Map中,鍵為ThreadLocal對象,值為T value
ThreadLocal是什么
一個可以保存變量在現場內部的類
ThreadLocal可以做什么
保存變量,使變量僅對對應的線程起作用
ThreadLocal怎樣使用
ThreadLocal.set(T value) :寫入一個值到ThreadLocal對象中
T ThreadLocal.get() :得到寫入的值
ThreadLocal.remove():移除寫入的值
ThreadLocal在哪些情況下使用
多線程多實例(每一個線程對應一個實例)的對象訪問
使用實例:使用THreadLocal保存Connection對象進行事務控制
/**
* 將Connection保存到當前線程中,單實例
*
* @author Administrator
*
*/
public class ConnectionContext {
private ThreadLocal<Connection> connectionThreadLocal = new ThreadLocal<>();
private static ConnectionContext instance = new ConnectionContext();
private ConnectionContext() {
}
public static ConnectionContext getInstance() {
return instance;
}
/**
* 將Connection對象綁定到當前線程中,鍵為connectionThreadLocal對象,值為connection對象
*
* @param connection
*/
public void bind(Connection connection) {
connectionThreadLocal.set(connection);
}
/**
* 得到綁定的Connection對象
*
* @return
*/
public Connection get() {
return connectionThreadLocal.get();
}
/**
* 移除綁定的Connection對象
*/
public void remove() {
connectionThreadLocal.remove();
}
}
原理分析
public class ThreadLocal<T> {
//設置一個value
public void set(T value) {
//獲取調用當前ThreadLocal對象的線程
Thread t = Thread.currentThread();
/*
*得到此線程的ThreadLocalMap,每一個線程中都有一個
*ThreadLocal.ThreadLocalMap threadLocals 對象
*
*ThreadLocalMap getMap(Thread t) {
* return t.threadLocals;
*}
*/
ThreadLocalMap map = getMap(t);
//將變量value保存入此map的值中,鍵為調用此方法的ThreadLocal對象
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
//獲取保存的value值
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;
}
}
/*
*如果沒放入值則返回初始化值
*默認初始化值為null,可以通過繼承重寫的方式設定初始化值
*protected T initialValue() {
* return null;
*}
*/
return setInitialValue();
}
static class ThreadLocalMap {
}
//清除value
public void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
...
...
}