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副本,每个线程间互不影响。