Может ли возможно использовать ThreadLocal <AtomicInteger>?

Итак, я просто увидел, что кто-то пытается использовать a ThreadLocal<AtomicInteger> в некотором Java-коде.
Теперь для связанного кода, который явно бесполезен, среди других проблем, вызвавших отказ в запросе.

И похоже, что это всегда было бы бесполезно: AtomicInteger (из пакета java.util.concurrent.atomic) предназначен для многопоточного доступа, а ThreadLocal делает каждый поток имеющим свое значение, поэтому зачем использовать это?

Мой вопрос: Может ли быть какая-нибудь ситуация, в которой был бы полезен ThreadLocal<AtomicInteger>?

Ответ 1

Да, мы можем придумать законный сценарий:

  • нам нужен локальный поток AtomicInteger в начале каждой задачи;
  • мы продолжаем распространять этот объект среди нескольких других потоков, например дочерние потоки, выделенные основным потоком задачи.

Не оценивая совокупность контекста, где это появляется, мы не можем судить.

Ответ 2

Предположим, нам нужен целочисленный счетчик на поток. ThreadLocal может работать только с объектами, поэтому логически нам нужно использовать int wrapper - Integer

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

alternatavely мы можем использовать AtomicInteger, а не потому, что он потокобезопасен, но поскольку он изменен

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

Версия 2 имеет намного лучшую производительность, чем версия 1, которая является настоящим убийцей производительности

Ответ 3

Я думаю, что есть только экзотические причины для ThreadLocal<AtomicInteger>. Могут быть ситуации, когда ThreadLocal не является единственной ссылкой на AtomicInteger, чтобы больше потоков могло получить к ней доступ. Когда вы окажетесь в такой ситуации, я думаю, вам лучше внимательно посмотреть на ваш дизайн...

Если вы не нуждаетесь в безопасности потока AtomicInteger, а просто его изменчивости, я предпочитаю использовать int[]. Меньше накладных расходов, затем AtomicInteger в сочетании с полным контролем:

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