给定一个线程对象是否可以访问ThreadLocal变量

时间:2016-09-30 00:26:57

标签: java multithreading

我想在另一个线程中访问线程局部变量。

e.g。

我有线程对象A用于线程1,

它有一个局部变量L1。

我有另一个线程Thread-2,如何在Thread-2中访问L1?感谢

2 个答案:

答案 0 :(得分:2)

否,因为内存可见性。所有ThreadLocal基础结构都假定对threadlocal对象的访问是线程限制的。如果另一个线程篡改了threadLocal对象的内容,则没有内存障碍让原始所有者线程知道它需要更新该对象的缓存版本,并且JIT不会知道在考虑其他线程的修改时推理它可以重新排序的说明;如果你更新它,原始线程仍然可以看到陈旧的版本,不知道发生了变化。

除了yshavit的观察之外,一般来说,篡改第三方库的内部结构是一个坏主意。

答案 1 :(得分:0)

是的,您可以使用反射。但是你一定不能。由于其他人指出的原因:你必然会破坏事物,或者得到意想不到的结果。

但纯粹为了有可能的学术示范,这种方法可以满足您的要求:

@NotThreadSafe
Object getValueForThread(ThreadLocal<?> threadLocal, Thread thread) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, NoSuchFieldException {
    Method getMap = ThreadLocal.class.getDeclaredMethod("getMap", new Class<?>[]{Thread.class});
    getMap.setAccessible(true);
    Object map = getMap.invoke(threadLocal, thread);
    Class<?> clazz = map.getClass();
    Method getEntry = clazz.getDeclaredMethod("getEntry", new Class<?>[]{ThreadLocal.class});
    getEntry.setAccessible(true);
    Object entry = getEntry.invoke(map, threadLocal);
    Field value = entry.getClass().getDeclaredField("value");
    value.setAccessible(true);
    return value.get(entry);
}

或者至少,它可以做你所要求的。由于没有可见性保证,调用此方法的线程可能会看到过时的值。再一次:不要这样做