private final ThreadLocal<Object> threadData = new ThreadLocal<Object>();
- 一句话概括:Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
- 线程数据隔离的秘诀:Thread有个ThreadLocalMap类型的属性,叫做threadLocals,该属性用来保存线程本地变量,这样每个线程都有自己的数据,就做到了不同线程间数据的隔离,保证了数据安全。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
- ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。从线程的角度看,目标变量就像是线程的本地变量,这也是类名中“Local"所要表达的意思。
ThreadLocal,ThreadLocalMap和Thread之间的关系
ThreadLocalMap是ThreadLocal的静态内部类,Thread有ThreadLocal.ThreadLocalMap类型的属性。
ThreadLocalMap看名字就知道是个map,没错,这就是个hashMap机制实现的map,用Entry数组来存储键值对,key是ThreadLocal对象,value则是具体的值。值得一提的是,为了方便GC,Entry继承了WeakReference,也就是弱引用。
static class ThreadLocalMap {
/**
* The entries in this hash map extend WeakReference, using
* its main ref field as the key (which is always a
* ThreadLocal object). Note that null keys (i.e. entry.get()
* == null) mean that the key is no longer referenced, so the
* entry can be expunged from table. Such entries are referred to
* as "stale entries" in the code that follows.
*/
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
//各种内部变量
}