[JAVA学习笔记-96]ThreadLocal
来源:互联网 发布:淘宝售假仅退款不退货 编辑:程序博客网 时间:2024/05/22 03:02
综述:
ThreadLocal可以理解为一个对象容器,这个容器为每个访问该容器的线程,封装了一个只对当前线程可见的对象。
也就是说,当多个线程共用一段代码时(例如同一个runnable对象分配给多个线程运行),ThreadLocal封装的对象
将会是线程安全的,只是访问的时候,需要用到set、get、remove、initValue等方法,否则,这些对象将会是多线程共享的,
是非线程安全的。
实现方法:
在Thread类中实现了一个 threadLocalMap<ThreadLocal key,T value>,执行ThreadLocal.set(T value)时,实质是获得当前Thread的这个 threadLocalMap ,将ThreadLocal对象作为Key(实质
是将该对象的HashCode作为Key)计算出下标(threadLocalMap是一个Entry[]),将指定的值存入数组中下标对应的位置。
在执行 ThreadLocal.get 时,再次获取当前Thread的 threadLocalMap,通过 ThreadLocal 对象作为key索引到保存的value,并返回。
【1、ThreadLocal 的 set方法:】
【2、ThreadLocal 的 getMap方法:】
【3、ThreadLocal 的 createMap 方法:】
【4、ThreadLocal.ThreadLocalMap 的构造方法:】
应用场景:
1、 web request handler
例如httpserver的hanler,向server注册一个GEThandler,每条http的GET请求都会调用此handler(假设只有一个handler对象,one thread per request),当并发的时候,handler中的
某些field会被多线程共享,且他们的值需要相互隔离(线程间不关心各自对这些field的修改),此时如果要线程安全,需要用ThreadLocal包装这些field。
2、 Reactor模式下的Accepter
多个连接并发的时候,Accepter可能需要用ThreadLocal隔离一些field,如果只有一个Accepter对象,而不是 new Thread(new Handler()).start(),那么可能需要用到ThreadLocal。
实例:
总结:
1、ThreadLocals are even more expensive than globals but they are certainly much better scoped.
2、ThreadLocal is for storing per-thread state past the execution scope of a method.
3、Another option is using synchronized to manage access to a shared member variable.
4、ThreadLocal,个人理解的应用场景为,当某个field为多线程共用,而field的值仅对各自线程有意义时,才用ThreadLocal包装隔离。
如果这个共用的field的值,对所有的线程都有意义,例如A线程修改了它,而B线程需要用到这个修改后的值,那么需要用 synchronized 或者用Atomicxxx族的对象来进行同步;
如果A线程修改的值,B线程并不关心,B线程只是与A线程共享了一段code而已,那么ThreadLocal可以用上。
通常情况下,尽量使用local variables在性能上更好。
ThreadLocal可以理解为一个对象容器,这个容器为每个访问该容器的线程,封装了一个只对当前线程可见的对象。
也就是说,当多个线程共用一段代码时(例如同一个runnable对象分配给多个线程运行),ThreadLocal封装的对象
将会是线程安全的,只是访问的时候,需要用到set、get、remove、initValue等方法,否则,这些对象将会是多线程共享的,
是非线程安全的。
实现方法:
在Thread类中实现了一个 threadLocalMap<ThreadLocal key,T value>,执行ThreadLocal.set(T value)时,实质是获得当前Thread的这个 threadLocalMap ,将ThreadLocal对象作为Key(实质
是将该对象的HashCode作为Key)计算出下标(threadLocalMap是一个Entry[]),将指定的值存入数组中下标对应的位置。
在执行 ThreadLocal.get 时,再次获取当前Thread的 threadLocalMap,通过 ThreadLocal 对象作为key索引到保存的value,并返回。
【1、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,则创建一个。*/ }
【2、ThreadLocal 的 getMap方法:】
ThreadLocalMap getMap(Thread t) { return t.threadLocals; }
【3、ThreadLocal 的 createMap 方法:】
void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }
【4、ThreadLocal.ThreadLocalMap 的构造方法:】
ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {table = new Entry[INITIAL_CAPACITY];int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); /*使用hashcode计算得到下标*/table[i] = new Entry(firstKey, firstValue);size = 1;setThreshold(INITIAL_CAPACITY);}private Entry[] table;static class Entry extends WeakReference<ThreadLocal> { /*注意这里的 WeakReference*//** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal k, Object v) { /*构造函数*/super(k);value = v;}}
应用场景:
1、 web request handler
例如httpserver的hanler,向server注册一个GEThandler,每条http的GET请求都会调用此handler(假设只有一个handler对象,one thread per request),当并发的时候,handler中的
某些field会被多线程共享,且他们的值需要相互隔离(线程间不关心各自对这些field的修改),此时如果要线程安全,需要用ThreadLocal包装这些field。
2、 Reactor模式下的Accepter
多个连接并发的时候,Accepter可能需要用ThreadLocal隔离一些field,如果只有一个Accepter对象,而不是 new Thread(new Handler()).start(),那么可能需要用到ThreadLocal。
实例:
public class Task implements Runnable{private static AtomicInteger num = new AtomicInteger(0);private ThreadLocal<Integer> id = new ThreadLocal<Integer>();@Overridepublic void run() {// TODO Auto-generated method stubid.set(num.incrementAndGet()); /*每个线程从AtomicInteger返回一个唯一的值*/System.out.println("id="+id.get()); /*每个线程的id值都是唯一的,并且相互之间感知不到,也不需要同步,因为此value实际上是Thread的local variable*/}}
总结:
1、ThreadLocals are even more expensive than globals but they are certainly much better scoped.
2、ThreadLocal is for storing per-thread state past the execution scope of a method.
3、Another option is using synchronized to manage access to a shared member variable.
4、ThreadLocal,个人理解的应用场景为,当某个field为多线程共用,而field的值仅对各自线程有意义时,才用ThreadLocal包装隔离。
如果这个共用的field的值,对所有的线程都有意义,例如A线程修改了它,而B线程需要用到这个修改后的值,那么需要用 synchronized 或者用Atomicxxx族的对象来进行同步;
如果A线程修改的值,B线程并不关心,B线程只是与A线程共享了一段code而已,那么ThreadLocal可以用上。
通常情况下,尽量使用local variables在性能上更好。
阅读全文
0 0
- [JAVA学习笔记-96]ThreadLocal
- JAVA学习笔记(四十三)- ThreadLocal
- 疯狂Java学习笔记(73)-----------ThreadLocal
- Java学习笔记(73)-----------ThreadLocal
- Java中的ThreadLocal的使用--学习笔记
- ThreadLocal学习笔记
- ThreadLocal学习笔记
- ThreadLocal学习笔记
- 【学习笔记】ThreadLocal
- ThreadLocal学习笔记
- ThreadLocal学习笔记
- [Java] Java ThreadLocal 学习
- java之ThreadLocal笔记
- Java 之 ThreadLocal学习
- java 之 ThreadLocal学习
- 学习java的ThreadLocal
- java基础-ThreadLocal学习
- java-ThreadLocal学习记录
- php语法技巧
- [JAVA学习笔记-95]REST框架浅析
- ajax的三种方式请求
- Android AbsoluteLayout(绝对)、RelativeLayout(相对)、RTL(RightToLeth)(布局小结二)
- 微信小程序例子——获取微信群唯一标识openGId
- [JAVA学习笔记-96]ThreadLocal
- UBUNTU16.10系统,显卡GTX1070,鼠标一直在左上角
- 实验四 DPCM编码
- download
- Python语法第3讲:数组
- Windows无法格式化改卷,改卷已脱机, 请尝试首先向改卷分配驱动器号或路径使其联机
- loadrunner GUI界面性能测试
- php 替换敏感字符串
- 数据库最常见的10个安全问题