ThreadLocal:線程本地存儲,為每個線程都創建了變量的副本,線程在訪問變量時,可以直接訪問自己內部的副本變量。
理解幾個概念:
在java中ThreadLocal是一個類。
ThreadMap是一個類,
Thread類是線程類。
ThreadLocal類中有一個ThreadMap的內部類。
Thread類中有一個成員變量是threadLocals
其類型為:ThreadLocalMap
ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocalMap的key值為ThreadLocal類型。
通過ThreadLocal為threadLocals添加值:
package processthread; /** * @author wangpei * @version *創建時間:2017年3月11日 下午2:16:48 * 類說明 */
public class ThreadLocalTest {public static ThreadLocal<Integer> longLocal=new ThreadLocal<Integer>();public static void main(String[] args) {ThreadLocalTest th=new ThreadLocalTest();ThreadLocalTest.ThreadTest thread=th.new ThreadTest ();thread.start();ThreadLocalTest.ThreadTest2 thread2=th.new ThreadTest2 ();thread2.start();}class ThreadTest extends Thread{public void run(){System.out.println("線程"+Thread.currentThread().getName()+"正在執行");ThreadLocalTest v=new ThreadLocalTest();v.longLocal.set(2);System.out.println(v.longLocal.get());} }class ThreadTest2 extends Thread{public void run(){System.out.println("線程"+Thread.currentThread().getName()+"正在執行");ThreadLocalTest v=new ThreadLocalTest();v.longLocal.set(3);System.out.println(v.longLocal.get());}}}
結果: 線程Thread-0正在執行
2
線程Thread-1正在執行
3
執行上面的結果可以看出,thread-0通過ThreadLocal寫入自己的副本變量2,thread-1通過ThreadLocal寫入自己的副本變量3
這兩個副本變量是線程中私有的空間。
源碼分析:
ThreadLocal的set方法:
public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);}
解釋:map中存放當前線程的threadLocals的值,如果map不為空,則
為map存放一個key值為當前ThreadLocal的Entry
ThreadLocalMap getMap(Thread t) {return t.threadLocals;}
ThreadLocal 的get方法:
ThreadLocalMap getMap(Thread t) {return t.threadLocals;}
返回線程t的threafLocals值。
ThreadLocal的應用:jdbc操作數據庫時,建立連接,如果在多線程情況下,必須加鎖實現同步,而此時,效率會大大降低。
可以為將connection寫進每個線程的threadLocals中,實現同步。這樣每個線程都有自己的connection副本,每個線程間互不影響。