Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Good Practice of using ThreadLocal in Java

I have a question regarding to how I should use ThreadLocal.

Context and Situation

There are several singleton objects that use ThreadLocal to create one copy per thread. This singleton object has a function 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() { ... }
}

... There are SingletonB, SingletonC, and so forth.

There is a singleton repository that caches the ThreadLocal singletons above. This class is also a ThreadLocal singleton -

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 ...
   }
}

This is currently how I access the ThreadLocal singletons through SingletonRepo

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

        singletonRepo.singletonA.helperFunction();
    }
}

Question

As you have seen in the context above, in order to access the ThreadLocal singletons, I first cached them in the SingletonRepo. When I need to use the ThreadLocal singleton, I get it from the cache reference. I have the following questions -

  1. Is it a bad practice to access the ThreadLocal singleton through a cache copy?
  2. Is it a better practice to always access the ThreadLocal singleton through SingletonA.getInstance() (Calling get() for the Singleton object)?
like image 484
thinket Avatar asked Nov 10 '22 21:11

thinket


1 Answers

A thread local cached copy is fine as it is simpler and more efficient. A cached copy where you are not sure it is thread local could be a problem.

A singleton by definition means there can only be one. I wouldn't what you have as a singleton and you have one per thread.

I would init() your thread local object in it's constructor.

BTW Your ThreadLocal should be private static final I suspect.

like image 118
Peter Lawrey Avatar answered Nov 14 '22 21:11

Peter Lawrey