Could ThreadLocal possibly be usefu

2020-08-20 08:41发布

问题:

So I just saw someone try to use a ThreadLocal<AtomicInteger> in some Java code.
Now, for the linked code, that's clearly useless, among other problems which caused the request to be denied.

And it seems like it would always be useless: AtomicInteger (from the java.util.concurrent.atomic package) is designed for multithread access, and ThreadLocal makes each thread have its own value, so why even use it?

My question is: Is there any situation in which a ThreadLocal<AtomicInteger> would be useful?

回答1:

Yes, we may come up with a legitimate scenario:

  1. we need a thread-local instance of AtomicInteger at the start of each task;
  2. we proceed to distribute this object among several other threads, for example child threads forked by the main task thread.

Without assessing the totality of the context where this appears, we cannot judge.



回答2:

Suppose we need an integer counter per thread. ThreadLocal can work only with objects so logically we need to use an int wrapper - Integer

ThreadLocal<Integer> count = new ThreadLocal<>();
...
count.set(count.get() + 1);

alternatavely we can use AtomicInteger, not because it's thread safe but because it's mutable

ThreadLocal<AtomicInteger> count = new ThreadLocal<>();
...
count.get().incrementAndGet();

Version 2 has a much better performance than version 1 which is a real performance killer



回答3:

I think there are only exotic reasons for ThreadLocal<AtomicInteger>. There might be situations where the ThreadLocal is not the only reference to the AtomicInteger so that more threads can access it. When you find yourself in such a situation, I think you better have a careful look at your design...

In case you do not need the thread safety of AtomicInteger but merely its mutability, I prefer using an int[]. Less overhead then AtomicInteger combined with full control:

ThreadLocal<int[]> count = new ThreadLocal<>();
...
count.set(new int[1]);
...
count.get()[0] = 42;
...
count.get()[0] += 4711;