Java长加法器sumThenReset并发

Java长加法器sumThenReset并发,java,concurrency,Java,Concurrency,我正在考虑从AtomicLong转换到使用LongAdder。我用它来计算到达服务器的请求,每1分钟我将结果写入数据库,然后再次开始计算。为此,我使用了AtomicLong的getAndSet方法,我打算用LongAdder的sumThenReset替换它 sumThenReset的文件说明如下: 返回的值不能保证是重置之前发生的最终值 那么我们在这里做了什么?这是否意味着根据定义,某些增量可能会丢失,并且不会在任何地方计算?阅读整个方法文档: 例如,此方法可适用于以下两种情况之间的静止点 多线

我正在考虑从AtomicLong转换到使用LongAdder。我用它来计算到达服务器的请求,每1分钟我将结果写入数据库,然后再次开始计算。为此,我使用了AtomicLong的getAndSet方法,我打算用LongAdder的sumThenReset替换它

sumThenReset的文件说明如下:

返回的值不能保证是重置之前发生的最终值


那么我们在这里做了什么?这是否意味着根据定义,某些增量可能会丢失,并且不会在任何地方计算?

阅读整个方法文档:

例如,此方法可适用于以下两种情况之间的静止点 多线程计算。如果有与此同步的更新 方法,则返回值不保证为最终值 发生在重置之前

安静意味着安静。也就是说,没有线程更新LongAdder。因此,为了回答您的问题,是的,一些增量可能会丢失

从类文档:

当有多个线程时,该类通常比AtomicLong更可取 更新用于收款等目的的公用金额 统计信息,不用于细粒度同步控制


可能您需要的是AtomicLong。

我发现,如果您将sumAndReset的实现扩展为:

long sum = longAdder.sum();<br>
longAdder.add(-sum);<br>
return sum;
long sum=longAdder.sum()
longAdder.add(-sum)
回报金额;
它工作得很好。
原因是,幕后的实现将存储拆分为多个单元。因此,实际原子加法的数量显著减少。因此,它针对原子添加进行了优化。sum、reset和sumanderset在单元格上迭代,sum或reset或两者都迭代,因此不是原子的。因此,使用负加法效果非常好。因为您完全删除了所求和的值,并且只返回与之相同的值,所以请保留所有计数。

如果争用是一个问题,您可以保存最新的总数,并将增量记录到当前总数中。没有丢失的更新,在重新启动后工作。