ThreadLocal学习笔记
来源:互联网 发布:kingcms php 编辑:程序博客网 时间:2024/05/01 02:44
可参考《实战Java高并发程序设计》4.3
ThreadLocal是一个线程的局部变量,只有当前线程可以访问的数据。所以是线程安全的。
为每一个线程分配不同的对象,需要在应用层面保证。ThreadLocal只是起到了简单容器的作用。如果在应用上为每一个线程分配了相同的对象,ThreadLocal也不能保证线程安全。
/** *ThreadLocal简单使用 */public class TestTheadLocal {static ThreadLocal<SimpleDateFormat> tl = new ThreadLocal<SimpleDateFormat>();public static class ParseDate implements Runnable {int i = 0;public ParseDate(int i) {this.i = i;}@Overridepublic void run() {if (tl.get() == null) {tl.set(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));}try {Date t = tl.get().parse("2016-06-29" + i % 60);System.out.println(i + ":" + t);} catch (ParseException e) {e.printStackTrace();}}}}
使用ThreadLocal为每一个线程都产生一个SimpleDateFormt对象实例。
实现原理(Jdk1.8的源码):其内部数据结构可以理解为一个HashMap,用户存储线程引用
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); }
get
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
/** * Remove the entry for key. */ private void remove(ThreadLocal<?> key) { Entry[] tab = table; int len = tab.length; int i = key.threadLocalHashCode & (len-1); for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { if (e.get() == key) { e.clear(); expungeStaleEntry(i); return; } } }
如果对象对于竞争的处理容易引起性能损失,应考虑使用ThreadLocal为每个线程分配单独的对象。典型案例就是多线程环境下产生随机数。
0 0
- ThreadLocal学习笔记
- ThreadLocal学习笔记
- ThreadLocal学习笔记
- 【学习笔记】ThreadLocal
- ThreadLocal学习笔记
- ThreadLocal学习笔记
- ThreadLocal与InheritableThreadLocal学习笔记
- [JAVA学习笔记-96]ThreadLocal
- JAVA学习笔记(四十三)- ThreadLocal
- 疯狂Java学习笔记(73)-----------ThreadLocal
- Java学习笔记(73)-----------ThreadLocal
- Java中的ThreadLocal的使用--学习笔记
- ThreadLocal笔记
- ThreadLocal笔记
- ThreadLocal笔记
- ThreadLocal笔记
- 学习ThreadLocal
- ThreadLocal 学习
- git克隆代码到本地
- ReactJs入门教程
- Problem-I
- JavaScript概述
- 专题四 第八道题
- ThreadLocal学习笔记
- std::move -- 强制转化为右值
- springmvc数据绑定
- 使用WPF创建SignalR服务端
- hibernate映射属性
- ASCII码表完整版
- linux c++消息队列(ftok,msgget,msgsnd,msgrcv,msgctl)
- 浏览器兼容性问题大汇总
- Mybatis 传入多个参数的方法