标签:exce sys try 相互 weakref 问题 null 带来 生命周期
public static void main(String[] args) {
ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
threadLocal.set(999);
// 模拟3个线程
for (int i=0; i<3; i++) {
new Thread(()-> {
for (int j = 0; j<2000; j++) {
if (null==threadLocal.get()) {
threadLocal.set(1);
} else {
threadLocal.set(threadLocal.get()+1);
}
}
System.out.println(Thread.currentThread().getName() + " " + threadLocal.get());
}).start();
}
System.out.println(Thread.currentThread().getName() + " " + threadLocal.get());
}
输出结果:
main 999 Thread-0 2000 Thread-1 2000 Thread-2 2000
上述示例说明:线程与线程之间相互隔离,且线程安全。ThreadLocal作用域为当前线程
// set方法一般都是set(key, value),因为ThreadLocalMap使用了当前线程作为key,所以省略了,get()方法也一样。
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; // 这个变量在Thread类中,ThreadLocal.ThreadLocalMap threadLocals = null;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
首次在调用 set方法时,会执行createMap,在createMap方法中又会创建一个ThreadLocalMap对象,我们再来看一下ThreadLocalMap这个构造方法
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
通过构造方法,我们可以看出ThreadLocal底层使用的就是HashMap结构
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
private static final int INITIAL_CAPACITY = 16;
private Entry[] table;
}
public static void main(String[] args) throws InterruptedException {
WeakHashMap<String, String> weakMap = new WeakHashMap<String, String>();
String key = new String("1");
String key2 = "2";
weakMap.put(key, "test");
weakMap.put(key2, "test2");
System.out.println(weakMap); // {1=test, 2=test2}
key = null;
key2 = null; // 不会被回收
System.gc();
System.out.println(weakMap); // {2=test2}
}
我们可以看出WeakHashMap针对key作了回收,而在整个map中并没有真正的回收此对象。在ThreadLocal中,它使用当前线程作为key的,如果线程生命周期结束后,即这个key以及对就的value都应该被GC掉
标签:exce sys try 相互 weakref 问题 null 带来 生命周期
原文地址:https://www.cnblogs.com/caoxb/p/13140146.html