前言
ThreadLocal位于java.lang包中
中文:线程局部变量
别称:线程本地变量
作用:线程堆栈中,调用的任何方法中都可以访问到一个以ThreadLocal对象作为Key对象的Value对象
ThreadLocal构造方法分析
public ThreadLocal() {
}
无参构造方法,创建ThreadLocal对象最常用的方式,没有之一
字段介绍
private final int threadLocalHashCode = nextHashCode();
private static AtomicInteger nextHashCode = new AtomicInteger();
private static final int HASH_INCREMENT = 0x61c88647;
threadLocalHashCode:每个对象持有的hashCode值,通过调用nextHashCode()返回,该值用于表示ThreadLocal对象作为Key对象的hashCode值
nextHashCode:ThreadLocal类持有的一个AtomicInteger对象,用于计算每个ThreadLocal对象对应的hashCode值,AtomicInteger为原子类,可以保证线程安全
HASH_INCREMENT:ThreadLocal类持有的一个常量,用于参与计算每个ThreadLocal对象对应的hashCode值时的增量
nextHashCode()方法分析
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}
用于计算出表示ThreadLocal对象的hashCode值的方法
1、读取常量值传入getAndAdd()方法中
内部调用ThreadLocal类持有的AtomicInteger对象nextHashCode的getAndAdd()方法,同时传入作为增量的常量值HASH_INCREMENT,该常量值是0x61c88647
2、向调用者返回一个int值,该int值即为当前ThreadLocal对象的hashCode值
注意:AtomicInteger是线程安全的原子类,该类的内部使用CAS算法,来保证线程安全的更新每个AtomicInteger对象持有的整型变量value值
总结
1、创建ThreadLocal对象的最佳方式:在某个类中,使用一个静态变量持有一个ThreadLocal对象,这也可以方便的在不同的线程中使用同一个ThreadLocal对象作为key对象,举例:在Android中,Looper对象的存储就是这么做的,另外由于静态变量的生命周期随着类本身在方法区中,类变量指向的ThreadLocal对象也不会被GC回收掉
2、在一个线程下创建一个ThreadLocal对象,那么ThreadLocal对象怎么与当前线程产生关联的,目前通过ThreadLocal的构造方法看不出来,我们需要继续学习ThreadLocal是如何添加元素的:Java并发之ThreadLocal源码分析(第二篇:添加元素)
下方图例(借的图)中,每个Thread对象都持有了一个ThreadLocalMap对象,而ThreadLocalMap持有的key-value元素中,key即是ThreadLocal对象