Java 您可以选择本地<;原子整数>;可能有用吗?
所以我在一些Java代码中只使用了Java 您可以选择本地<;原子整数>;可能有用吗?,java,multithreading,atomic,Java,Multithreading,Atomic,所以我在一些Java代码中只使用了ThreadLocal。 现在,对于链接代码来说,这显然是无用的,还有其他导致请求被拒绝的问题 而且它似乎总是无用的:AtomicInteger(来自java.util.concurrent.atomic包)是为多线程访问而设计的,而ThreadLocal使每个线程都有自己的值,那么为什么还要使用它呢 我的问题是:在任何情况下,ThreadLocal是否有用?是的,我们可能会提出一个合理的方案: 在每个任务开始时,我们需要一个AtomicInteger的线程本地
ThreadLocal
。现在,对于链接代码来说,这显然是无用的,还有其他导致请求被拒绝的问题 而且它似乎总是无用的:
AtomicInteger
(来自java.util.concurrent.atomic包)是为多线程访问而设计的,而ThreadLocal
使每个线程都有自己的值,那么为什么还要使用它呢
我的问题是:在任何情况下,
ThreadLocal
是否有用?是的,我们可能会提出一个合理的方案:
AtomicInteger
的线程本地实例李>
如果不评估出现这种情况的整个上下文,我们就无法判断。假设每个线程需要一个整数计数器。ThreadLocal只能处理对象,因此逻辑上我们需要使用int-wrapper-Integer
ThreadLocal<Integer> count = new ThreadLocal<>();
...
count.set(count.get() + 1);
ThreadLocal count=new ThreadLocal();
...
count.set(count.get()+1);
另外,我们可以使用AtomicInteger,不是因为它是线程安全的,而是因为它是可变的
ThreadLocal<AtomicInteger> count = new ThreadLocal<>();
...
count.get().incrementAndGet();
ThreadLocal count=new ThreadLocal();
...
count.get().incrementAndGet();
版本2的性能比版本1要好得多,版本1是一个真正的性能杀手我认为对于
ThreadLocal
,只有一些奇怪的原因。在某些情况下,ThreadLocal
不是对AtomicInteger
的唯一引用,因此更多线程可以访问它。当你发现自己处于这种情况下,我认为你最好仔细看看你的设计
如果您不需要AtomicInteger
的线程安全性,而只需要它的易变性,我更喜欢使用int[]
。与AtomicInteger结合完全控制相比,开销更小:
ThreadLocal<int[]> count = new ThreadLocal<>();
...
count.set(new int[1]);
...
count.get()[0] = 42;
...
count.get()[0] += 4711;
ThreadLocal count=new ThreadLocal();
...
count.set(新整数[1]);
...
count.get()[0]=42;
...
count.get()[0]+=4711;
这不是一条有趣的评论,但我真的想不出任何评论。我同意你的推理,并认为它排除了ThreadLocal有用的任何情况。除非使用反射,否则无法访问另一个线程的ThreadLocal。1。这是否意味着我们可能需要这样做,因为我们可能需要这样做?2.但在这种情况下,首先使用ThreadLocal是明智的。虽然我同意,如果没有明确的上下文,很难排除问题。@selig如果所有这些都发生在服务器代码中,则每个客户端请求都由其自己的线程单独提供服务,并且主线程启动其自己的线程组并分发AtomicInteger
,这可能需要从以前的任务中重用(每次都不是一个新的对象)。是的,这是一个延伸,但这并不重要:一旦你有了需要,你就有了它,而且你没有罪。是的,这听起来像是一个合法的场景(多线程服务器,一个线程/客户机交给多个工作人员)如果有更好的答案,我会暂缓接受。这一点很好。我使用AtomicReference将结果对象从可运行代码传递回调用程序-不是因为我需要原子性,而是因为我需要一个可变引用,而且我太懒了,无法为此创建类。所以,仅仅为了有一个编写良好的包装器?也许因此,stdlib应该提供一个可变整数类或其他什么。AtomicInteger
使用了volatile
和一些隐藏的同步。因此,我不清楚在这种情况下,它的开销与Integer
的装箱开销相比如何。您是否检查过“版本1是一个真正的性能杀手”具有正确基准的语句?我使用JMH进行了测试。~~~基准模式Cnt分数错误单位ThreadLocalBenchmark.testAtomicInteger ss 20000 92.736±1.461 us/op ThreadLocalBenchmark.testInteger ss 20000 111.812±2.375 us/op~~~原子整数更快。