java - 在 Java 中使用 ThreadLocal 的良好实践

标签 java concurrency parallel-processing thread-local

我有一个关于如何使用 ThreadLocal 的问题。

背景和情况

有几个单例对象使用 ThreadLocal 为每个线程创建一个副本。这个单例对象有一个函数 foo()

public class SingletonA {
    protected static ThreadLocal<SingletonA> singleton = new ThreadLocal<SingletonA>() {
        @Override
        protected SingletonA initialValue() {
            return new SingletonA();
        }
    };

    private SingletonA() { ... }
    public static SingletonA getInstance() { return singleton.get(); }
    public static void remove() { singleton.remove(); }
    public static void foo() { ... }
}

……有SingletonB、SingletonC等。

上面有一个缓存ThreadLocal单例的单例仓库。这个类也是一个 ThreadLocal 单例 -

public class SingletonRepo {
        protected static ThreadLocal<SingletonRepo> singleton = new ThreadLocal<SingletonRepo>() {
        @Override
        protected SingletonRepo initialValue() {
            return new SingletonRepo();
        }
    };

    private SingletonRepo() { ... }
    public static SingletonRepo getInstance() { return singleton.get(); }
    public static void remove() { singleton.remove(); }

    public SingletonA singletonA;
    // same thing for singletonB, singletonC, ...

   public static init() {
        // Caching the ThreadLocal singleton
        singletonA = SingletonA.getInstance();
        // Same thing for singletonB, singletonC ...
   }
}

这就是目前我通过 SingletonRepo 访问 ThreadLocal 单例的方式

public class App {
    public SingletonRepo singletonRepo;
    public static void main(String [] args) {
        singletonRepo = SingletonRepo.getInstance();
        singletonRepo.init();

        singletonRepo.singletonA.helperFunction();
    }
}

问题

正如您在上面的上下文中看到的,为了访问 ThreadLocal 单例,我首先将它们缓存在 SingletonRepo 中。当我需要使用 ThreadLocal 单例时,我从缓存引用中获取它。我有以下问题-

  1. 通过缓存副本访问 ThreadLocal 单例是一种不好的做法吗?
  2. 总是通过 SingletonA.getInstance() 访问 ThreadLocal 单例是更好的做法吗(为 Singleton 对象调用 get() )?

最佳答案

线程本地缓存副本很好,因为它更简单、更高效。您不确定它是本地线程的缓存副本可能是个问题。

根据定义,单例意味着只能有一个。我不会将您作为单例拥有,而您每个线程都有一个。

我会在它的构造函数中 init() 你的线程局部对象。

顺便说一句,我怀疑你的 ThreadLocal 应该是 private static final

关于java - 在 Java 中使用 ThreadLocal 的良好实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27536194/

相关文章:

Java菜单问题

java - 优化嵌套 if 语句中的嵌套 for 循环

concurrency - 如何并行制作阻塞调用列表并以先到先得的方式获得结果?

java - 通过多线程访问文件

javascript - Bluebird JS : Make a function run in parallel

java - 在 Java 中逐字地在多个字符之后包装字符串

java - Android String.split ("") 返回额外的元素

java - 非阻塞和阻塞并发

使用 OpenMP 的教程计算 Pi 算法

algorithm - 用于检测无向图中循环的最佳并行算法