Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从声明Java ThreadLocal对象的类以外的类访问该对象_Java_Multithreading_Threadpool_Thread Local - Fatal编程技术网

从声明Java ThreadLocal对象的类以外的类访问该对象

从声明Java ThreadLocal对象的类以外的类访问该对象,java,multithreading,threadpool,thread-local,Java,Multithreading,Threadpool,Thread Local,我声明了一个ThreadLocal对象,并设置了一个如下所示的值 Public Class Blah { private ThreadLocal<Set<Integer>> numberThreaLocalObj= new ThreadLocal<>(); void setValue() { Set<Integer> numberSet = new HashSet<>(); numberSet .add(1);

我声明了一个ThreadLocal对象,并设置了一个如下所示的值

Public Class Blah {

private ThreadLocal<Set<Integer>> numberThreaLocalObj= new ThreadLocal<>();

  void setValue() {
    Set<Integer> numberSet = new HashSet<>();
    numberSet .add(1);
    threaLocalObj.set(numberSet) 
  }
} 
公共类废话{
private ThreadLocal number realocalobj=new ThreadLocal();
void setValue(){
Set numberSet=newhashset();
编号集合添加(1);
threaLocalObj.set(数字集)
}
} 
在同一个线程中,是否在类之外引用这个numberThreaLocalObj变量

我发现一些代码似乎可以清除所有的Threadlocal,但我只需要根据条件清除这个特定的Threadlocal变量

不幸的是,这是一个继承的技术设计


编辑-如我的回答中所述找到解决方案。

它是threadlocal这一事实与此无关。你在问:我可以从另一个类访问私有字段吗

答案是:不是真的。如果您有想要访问此字段的Blah实例(它是一个非静态字段;因此,Blah的每个实例都有一个threadlocal),则可以使用java.lang.reflection:

Field f = Blah.class.getDeclaredField("numberThreaLocalObj");
f.setAccessible(true);
ThreadLocal<?> t = f.get(someInstanceOfBlah);
t.set(null);
Field f=Blah.class.getDeclaredField(“numberThreaLocalObj”);
f、 setAccessible(true);
ThreadLocal t=f.get(someInstanceOfBlah);
t、 set(空);

一旦添加了适当的异常保护,就可以这样做。

它是threadlocal这一事实无关紧要。你在问:我可以从另一个类访问私有字段吗

答案是:不是真的。如果您有想要访问此字段的Blah实例(它是一个非静态字段;因此,Blah的每个实例都有一个threadlocal),则可以使用java.lang.reflection:

Field f = Blah.class.getDeclaredField("numberThreaLocalObj");
f.setAccessible(true);
ThreadLocal<?> t = f.get(someInstanceOfBlah);
t.set(null);
Field f=Blah.class.getDeclaredField(“numberThreaLocalObj”);
f、 setAccessible(true);
ThreadLocal t=f.get(someInstanceOfBlah);
t、 set(空);

一旦添加了适当的异常保护,我就可以这样做。

我可以使用以下代码来识别我感兴趣的特定threadlocal对象 代码来自上一篇帖子,由@lyaffe回答

我的线程位于另一个类中的本地对象

 private ThreadLocal<Set<Integer>> numberSetTL = new NamedThreadLocal<>("MY_NAMED_TL_NAME");
private ThreadLocal numbersetl=new NamedThreadLocal(“MY_NAMED_TL_NAME”);
我稍微修改了代码,删除了一个特定的名称。要删除的ThreadLocal必须是一个名为ThreadLocal的Spring对象

 private void cleanThreadLocals() {
        try {
            // Get a reference to the thread locals table of the current thread
            Thread thread = Thread.currentThread();
            Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");
            threadLocalsField.setAccessible(true);
            Object threadLocalTable = threadLocalsField.get(thread);

            // Get a reference to the array holding the thread local variables inside the
            // ThreadLocalMap of the current thread
            Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
            Field tableField = threadLocalMapClass.getDeclaredField("table");
            tableField.setAccessible(true);
            Object table = tableField.get(threadLocalTable);

            // The key to the ThreadLocalMap is a WeakReference object. The referent field of this object
            // is a reference to the actual ThreadLocal variable
            Field referentField = Reference.class.getDeclaredField("referent");
            referentField.setAccessible(true);

            for (int i=0; i < Array.getLength(table); i++) {
                // Each entry in the table array of ThreadLocalMap is an Entry object
                // representing the thread local reference and its value
                Object entry = Array.get(table, i);
                if (entry != null) {
                    // Get a reference to the thread local object and remove it from the table
                    ThreadLocal threadLocal = (ThreadLocal)referentField.get(entry);
                    if(threadLocal instanceof NamedThreadLocal) {

                        if("MY_NAMED_TL_NAME".equalsIgnoreCase(threadLocal.toString())) {
                            threadLocal.remove();
                            LOG.debug(tlName + " - ThreadLocal found and removed.");
                        }

                }
                }
            }
        } catch(Exception e) {
            // We will tolerate an exception here and just log it
            throw new IllegalStateException(e);
        }
    }
private void cleanThreadLocals(){
试一试{
//获取对当前线程的线程局部变量表的引用
Thread-Thread=Thread.currentThread();
字段threadLocalsField=Thread.class.getDeclaredField(“threadLocals”);
threadLocalsField.setAccessible(true);
对象threadLocalTable=threadLocalsField.get(线程);
//获取对数组的引用,该数组在
//当前线程的ThreadLocalMap
类threadLocalMapClass=Class.forName(“java.lang.ThreadLocal$ThreadLocalMap”);
Field tableField=threadLocalMapClass.getDeclaredField(“表格”);
tableField.setAccessible(true);
objecttable=tableField.get(threadLocalTable);
//ThreadLocalMap的键是WeakReference对象。此对象的referent字段
//是对实际ThreadLocal变量的引用
字段referentField=Reference.class.getDeclaredField(“referent”);
referencetfield.setAccessible(true);
for(int i=0;i
我可以使用以下代码来识别我感兴趣的特定threadlocal对象 代码来自上一篇帖子,由@lyaffe回答

我的线程位于另一个类中的本地对象

 private ThreadLocal<Set<Integer>> numberSetTL = new NamedThreadLocal<>("MY_NAMED_TL_NAME");
private ThreadLocal numbersetl=new NamedThreadLocal(“MY_NAMED_TL_NAME”);
我稍微修改了代码,删除了一个特定的名称。要删除的ThreadLocal必须是一个名为ThreadLocal的Spring对象

 private void cleanThreadLocals() {
        try {
            // Get a reference to the thread locals table of the current thread
            Thread thread = Thread.currentThread();
            Field threadLocalsField = Thread.class.getDeclaredField("threadLocals");
            threadLocalsField.setAccessible(true);
            Object threadLocalTable = threadLocalsField.get(thread);

            // Get a reference to the array holding the thread local variables inside the
            // ThreadLocalMap of the current thread
            Class threadLocalMapClass = Class.forName("java.lang.ThreadLocal$ThreadLocalMap");
            Field tableField = threadLocalMapClass.getDeclaredField("table");
            tableField.setAccessible(true);
            Object table = tableField.get(threadLocalTable);

            // The key to the ThreadLocalMap is a WeakReference object. The referent field of this object
            // is a reference to the actual ThreadLocal variable
            Field referentField = Reference.class.getDeclaredField("referent");
            referentField.setAccessible(true);

            for (int i=0; i < Array.getLength(table); i++) {
                // Each entry in the table array of ThreadLocalMap is an Entry object
                // representing the thread local reference and its value
                Object entry = Array.get(table, i);
                if (entry != null) {
                    // Get a reference to the thread local object and remove it from the table
                    ThreadLocal threadLocal = (ThreadLocal)referentField.get(entry);
                    if(threadLocal instanceof NamedThreadLocal) {

                        if("MY_NAMED_TL_NAME".equalsIgnoreCase(threadLocal.toString())) {
                            threadLocal.remove();
                            LOG.debug(tlName + " - ThreadLocal found and removed.");
                        }

                }
                }
            }
        } catch(Exception e) {
            // We will tolerate an exception here and just log it
            throw new IllegalStateException(e);
        }
    }
private void cleanThreadLocals(){
试一试{
//获取对当前线程的线程局部变量表的引用
Thread-Thread=Thread.currentThread();
字段threadLocalsField=Thread.class.getDeclaredField(“threadLocals”);
threadLocalsField.setAccessible(true);
对象threadLocalTable=threadLocalsField.get(线程);
//获取对数组的引用,该数组在
//当前线程的ThreadLocalMap
类threadLocalMapClass=Class.forName(“java.lang.ThreadLocal$ThreadLocalMap”);
Field tableField=threadLocalMapClass.getDeclaredField(“表格”);
tableField.setAccessible(true);
objecttable=tableField.get(threadLocalTable);
//ThreadLocalMap的键是WeakReference对象。此对象的referent字段
//是对实际ThreadLocal变量的引用
字段referentField=Reference.class.getDeclaredField(“referent”);