ThreadLocal
来源:互联网 发布:安卓6.0短信拦截源码 编辑:程序博客网 时间:2024/06/19 06:09
ThreadLocal类解决的是变量在不同线程间的隔离性,每个线程拥有自己的不同值。Java.lang.ThreadLocal类来实现线程本地存储的功能。ThreadLocal为每个使用该变量的线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量,每个线程内部都会有一个该变量,且在线程内部任何地方都可以使用,线程之间互不影响,这样一来就不存在线程安全问题,也不会严重影响程序执行性能。
每一个线程的Thread对象中都有一个ThreadLocalMap对象,这个对象存储了一组以ThreadLocal.threadLocalHashCode为键,以本地线程变量为值的K-V值对。ThreadLocal对象就是当前线程的ThreadLocalMap的访问入口,每一个ThreadLocal对象都包含了一个独一无二的threadLocalHashCode的值,使用这个值就可以在线程K-V值对中找回对应的本地线程变量。
get()方法是用来获取ThreadLocal在当前线程中保存的变量副本,set()用来设置当前线程中变量的副本,remove()用来移除当前线程中变量的副本,initialValue()是一个protected方法,一般是用来在使用时进行重写的,它是一个延迟加载方法。操作的步骤都是先取得当前线程t,然后通过getMap(t)方法获取到一个map,map的类型为ThreadLocalMap。然后接着下面获取到<key,value>键值对。
总结:实际上通过ThreadLocal创建的副本是存储在每个线程自己内ThreadLocalMap类型对象中的。ThreadLocalMap的键值为ThreadLocal对象的原因是每个线程中可有多个ThreadLocal变量。http://www.cnblogs.com/dolphin0520/p/3920407.html
最常见的ThreadLocal使用场景是用来解决数据库连接、Session管理等。
public class Test { ThreadLocal<Long> longLocal = new ThreadLocal<Long>(); ThreadLocal<String> stringLocal = new ThreadLocal<String>(); public void set() { longLocal.set(Thread.currentThread().getId()); stringLocal.set(Thread.currentThread().getName()); } public long getLong() { return longLocal.get(); } public String getString() { return stringLocal.get(); } public static void main(String[] args) throws InterruptedException { final Test test = new Test(); test.set(); System.out.println(test.getLong()); System.out.println(test.getString());Thread thread1 = new Thread(){ public void run() { test.set(); System.out.println(test.getLong()); System.out.println(test.getString()); }; }; thread1.start(); thread1.join(); System.out.println(test.getLong()); System.out.println(test.getString()); }}
输出结果如下:
解释:在这段代码中由两个ThreadLocal变量分别是longLocal和stringLocal,这两个变量在thread1和main线程中都保存了自己的变量副本,且变量的值在两个线程之间相互隔离在每个线程内部,把自己线程内部的longLocal变量和stringLocal变量存储在该线程内部的ThreadLocalMap对象中,在这个ThreadLocalMap对象中存储的内容是ThreadLocal.threadLocalHashCode为键,以本地线程变量为值的K-V值对,例如在上面的例子中thread1内的ThreadLocalMap对象存储的内容是<longLocal对象的hashcode值,thread1线程内的longLocal的值8>,<stringLocal对象的hashcode值,thread1线程内的stringLoccal的值Thread-0>,在main线程内的ThreadLocalMap对象存储的内容是<longLocal对象的hashcode值,main线程内的longLocal的值1>,<stringLocal对象的hashcode值,thread1线程内的stringLoccal的值main>。每个线程内部可以有多个threadLocal变量,在ThreadLocalMap中以ThreadLocal变量的hash值为键,以该值在该线程内部的变量为值的<key,value>对。
补充:使用InheritableThreadLocal类可以让子线程从父线程中取得值,但是继承之后在父线程或子线程中再修改就互不影响了。《Java多线程编程核心技术》
http://qifuguang.me/2015/09/02/[Java并发包学习七]解密ThreadLocal/
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- ThreadLocal
- threadlocal
- ThreadLocal
- ThreadLocal
- 面试题38:数字在排序数组中出现的次数
- SCU2016-03 A题 trie树 + dp
- poj2115C Looooops(扩展欧几里德)
- MARKDOWN语法总结
- 常见ORA异常
- ThreadLocal
- 39. Combination Sum
- Unix网络编程 卷1 第11章:名字与地址转换(udp_client_connect_connect)
- HashMap与ConcurrentHashMap的区别
- 【JZOJ 4772】 运输妹子
- python自学笔记
- HeadFirst 设计模式 笔记
- HDU:Substrings
- [知其然不知其所以然-37] All about RTC