ThreadLocal理解
- 使用ThreadLocal的时候我们保证了每个线程可以隔离使用对象,避免线程间的数据干扰。
常用例子:
public class ThreadLocalTest { public static void main(String[] args) throws InterruptedException {
ThreadLocal tl=new ThreadLocal();
tl.set("123");
System.out.println(Thread.currentThread()+":"+tl.get());
Thread t=new Thread(
new Runnable() {
public void run() {
tl.set("456");
System.out.println(Thread.currentThread()+":"+tl.get());
}
});
t.start();
Thread.sleep(1000);
System.out.println(Thread.currentThread()+":"+tl.get());
}}
结果:
Thread[main,5,main]:123
Thread[Thread-0,5,main]:456
Thread[main,5,main]:123
从上面的例子可以看出来,每个线程保存的对象是隔离的!
- 代码分析
下面是Thread里面定义的对象,它的声明是在ThreadLocal里面的一个静态子类对象ThreadLocal.ThreadLocalMap threadLocals = null;
这里是ThreadLocal的对象定义static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
//可以看出key为当前的ThreadLocal对象,value为保存的数据对象
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
}
下面set/get/getMap/createMap方法,可以存储数据
public void set(T value) { //获取当前线程
Thread t = Thread.currentThread();
//根据当前的线程获取数据
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
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();
}
/**
* 这里可以看出返回的数据是当前的线程变量
*/
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
从上面可以看出写的代码示例,返回值是不同的因为线程是独立的,独立线程会有自己的单独数据存储map,
至于ThreadLocal当作key是为了防止多个ThreadLocal在同一个线程当中做区分
- ThreadLocal做保存数据的key唯一性
//ThreadLocal类中有一个被final修饰的类型为int的threadLocalHashCode,它在该ThreadLocal被构造的时候就会生成,相当于一个ThreadLocal的ID private final int threadLocalHashCode = nextHashCode();
//threadLocalHashCode值来源于这里
private static AtomicInteger nextHashCode =new AtomicInteger();
private static final int HASH_INCREMENT = 0x61c88647;
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}
以上是 ThreadLocal理解 的全部内容, 来源链接: utcz.com/z/515605.html