在下面的示例中,有人能判断LongAccumulator是否是AtomicInteger的更好的替代方案吗?
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class IncrementThread implements Runnable{
AtomicInteger atomicint = new AtomicInteger();
public IncrementThread(AtomicInteger atominint) {
this.atomicint = atominint;
}
@Override
public void run() {
while(true)
if(atomicint.incrementAndGet()==4){doSomething(); atomicint.set(0);}
}
private void doSomething() {
System.out.println(Thread.currentThread().getName() + " : counter reached to 4");
}
public static void main(String[] args) {
AtomicInteger atomicint = new AtomicInteger();
IncrementThread incThread1 = new IncrementThread(atomicint);
IncrementThread incThread2 = new IncrementThread(atomicint);
IncrementThread incThread3 = new IncrementThread(atomicint);
ExecutorService threadPool = Executors.newCachedThreadPool();
threadPool.execute(incThread1);
threadPool.execute(incThread2);
threadPool.execute(incThread3);
}
}发布于 2016-03-12 18:41:09
在这个非常精确的例子中(实际上没有什么用处),这两个类似乎是等价的。
使用LongAccumulator,可以将整个if语句作为lambda表达式传递。但是:LongAccumulator的java声明提供的函数应该是无副作用的,这是没有实现的(doSomething写到system )。
发布于 2016-12-20 11:33:37
我想您可能会以与本例中的LongAccumulator相同的方式使用AtomicInteger。在这种情况下,答案是no。
当调用get()之类的方法时,LongAccumulator会累积值并只计算结果。您还可以清除类似的LongAccumulator.reset()方法,当它具有4个值时。但是LongAccumulator中的所有这些方法都不是线程安全的,您可能会得到不可预测的结果,因为您使用多个线程进行读取和更新。
LongAccumulator是好的,当您知道许多不同的线程将是更新值,但读取很少越来越多,您应该确保读取或重置只发生在一个线程,如果您关心的是同步。但如果你不这样做,LongAccumulator可能会更好。例如,当您想要统计统计数据时,如果您想要获得统计数据,您很可能不是指“调用时的统计”,而是指类似“当前”的结果。这种推理也适用于LongAdder。
在您的示例中,有两个可能的改进。首先,您可以使用:
while(true)
if(atomicint.incrementAndGet()==4){doSomething(); atomicint.compareAndSet(4, 0);}现在检查一下,您是否重置了相同的原子变量状态。
另一个可能的改进是--不要使用AtomicLong或LongAccumulator,只需使用简单的long变量和keyword关键字。在这里,它将更简单、更适用,因为在本例中,您不使用功能(正如我在第一次改进中提到的那样)。
您可以更多地了解文档和类的来源。
https://stackoverflow.com/questions/35961524
复制相似问题