通常狀況下,咱們將一個線程中的局部變量保存在線程之中。本文以裝Connection爲例子。作法以下:web
第一步:ide
private static ThreadLocal<Connection> tl;this
第二步:spa
public static Connection getConnection() {
Connection con = tl.get();
if (con == null) {
try {
con = ds.getConnection();.net
tl.set(con);線程
} catch (Exception e) {
throw new RuntimeException(e);
}
}orm
return con;對象
}事務
這樣咱們在處理事務時就會有使用同一對象,或者變量。ci
那咱們來看下源碼是這些方法是怎麼實現的呢?
一、首先咱們先看下源碼:
/**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of
* this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();//這裏是拿到當前的線程
ThreadLocalMap map = getMap(t);// 在這個進一步查看源碼時,會看到其實就是MAP對象。以當前的t爲key
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
也就是說上面的代碼,是將數據裝在MAP裏面、
那麼咱們在來看下get()方法是怎麼實現的呢?
二、get()
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
相信你們看到了這裏應該就明白了吧,數據就是這麼放的,從此咱們在解決一些處理事務的時候,能夠擁這個來解決、
每一個thread中都存在一個map,map的類型是ThreadLocal,ThreadLocalMap,Map中的key爲一個threadlocal實例。這個map的也使用了弱引用。不過弱引用是針對key,每一個key都弱引用指向threadlocal,當咱們指向的爲空,就會被gc回收。