简述
一种线程绑定机制,每个线程都拥有对象的独立副本,不会与其他线程冲突,从而避免了并发与同步问题。
结构
每个线程都有一个ThreadLocalMap,其中Key为ThreadLocal对象,Value为用户对象的值
****ThreadLocal只是作为Key标识,并不存放任何数据,真正存放数据的是每个线程中的ThreadLocalMap。所以ThreadLocal一般应该定义成静态变量。****
也不是一般人认为的Key是线程的名字或者标识
实现
public class ThreadLocal {
public T get() {
// 获取当前线程
Thread t = Thread.currentThread();
// 从当前线程中获取ThreadLocalMap变量
ThreadLocalMap map = getMap(t);
if (map != null) {
// 以当前的ThreadLocal对象作为Key,从Map中获取对应的值
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
}
public class Thread implements Runnable {
// 每个线程都有一个ThreadLocalMap对象
ThreadLocal.ThreadLocalMap threadLocals = null;
}
应用
避免同步或每次使用都创建新对象
针对Random、DateFormatter等非线程安全类,实现每个线程一个对象
数据库连接等资源限制类,实现每个线程一个连接线程内跨方法的数据传递
例如Hibernate的Session绑定(实现延迟加载和事务处理,保证整个处理过程使用同一个session)