【问题标题】:i am setting value of threadlocal in one class can i access the value in another class我在一个类中设置threadlocal的值我可以访问另一个类中的值吗
【发布时间】:2013-07-12 12:51:16
【问题描述】:

在下面的代码中,我将临时线程本地值存储在一个线程本地类中。并将该值设置到另一个类中..

List<String> spaces=new ArrayList<String>();
spaces.add(spaceKey);
ThreadLocal<List<String>> threadLocal=new ThreadLocal<List<String>>();
threadLocal.set(spaces);  
setShardHolder(threadLocal);

我在另一个类中有 getter 和 setter

private ThreadLocal<List<String>> shardHolder;
public ThreadLocal<List<String>> getShardHolder() {
return shardHolder;
}
public void setShardHolder(ThreadLocal<List<String>> shardHolder) {
this.shardHolder = shardHolder;
}

我无法使用 getter 访问值

【问题讨论】:

  • 问题是什么?

标签: java


【解决方案1】:

您似乎没有理解 ThreadLocal 变量的工作原理。 ThreadLocal 实例有点像单个值的容器。如果您在其中存储一些内容,它将与当前线程相关联,您可以稍后从同一个线程中检索它。

当然,如果您将某些内容存储在 ThreadLocal 实例中,并尝试从不同的 ThreadLocal 实例中检索它,您将始终得到 null:它们不是同一个容器。

所以 ThreadLocal 通常隐藏在静态方法后面。例如,假设您要将用户与当前线程相关联。你会做的

public class CurrentUser {
    private static final ThreadLocal<User> CURRENT = new ThreadLocal<User>();

    public static User getCurrentUser() {
        return CURRENT.get();
    }

    public static void setCurrentUser(User user) {
        CURRENT.set(user);
    }
}

那我们来设计一个场景:

public class Test
    public static void main(String[] args) {
        CurrentUser.set(new User("foo"));
        System.out.println(CurrentUser.get()); // prints foo
        new Thread(new Runnable() {
            public void run() {
                System.out.println(CurrentUser.get()); // prints null: different thread
            }
        }).start();
    }
}

【讨论】:

    【解决方案2】:

    要获取任何对象的值,您需要对其进行引用。如果您可以在一个类中引用 ThreadLocal,您就可以访问它。 (ThreadLocal 在这方面并没有什么特别之处)

    我建议你试试看。

    我无法使用 getter 访问值

    这意味着你做错了什么,但由于你没有说为什么你不能这样做,所以不清楚那是什么。

    如果你说你可以获得一个 ThreadLocal,但调用它返回null,这意味着你正在另一个线程中运行它。这就是 ThreadLocal 的设计目的。

    【讨论】:

      【解决方案3】:

      从 javadoc 来看,ThreadLocal 实例通常是类中的私有静态字段,它们希望将状态与线程相关联。例如:

          private static final ThreadLocal<List<String>> SHARD_HOLDER;
          public static List<String> getSpacesList() {
              return SHARD_HOLDER.get();
          }
      
          public static void setSpacesList(List<String> spacesList) {
              SHARD_HOLDER.set(spacesList);
          }
      

      【讨论】:

        【解决方案4】:

        您可以将您的线程本地设置为静态变量并以这种方式使用它,看看这篇文章我确定其中一个示例将适合您的用例。

        http://java.dzone.com/articles/java-thread-local-%E2%80%93-how-use

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-07
          • 1970-01-01
          • 1970-01-01
          • 2022-09-29
          • 1970-01-01
          相关资源
          最近更新 更多