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