Может ли возможно использовать 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;