这个版本运行良好,但出于培训目的,我想使用原子操作而不是锁来重新实现它。
如果在滚动期发生时需要对数据进行多次更改,则需要锁定,否则会出现问题。任何时候你有多个“原子操作”,你都需要一个锁来防止竞争条件。例如,在您的情况下,如果在您滚动时将其他内容添加到队列中怎么办?
我可以使用哪种其他方法?
我不是 100% 确定您为什么需要将信息排队。如果您只计算请求数和下载的数据总大小,那么您应该能够使用单个AtomicReference<CountSum>
. 该类CountSum
将存储您的两个值。然后,当有人需要增加它时,他们会执行以下操作:
CountSum newVal = new CountSum();
do {
CountSum old = countSumRef.get();
newVal.setCount(old.getCount() + 1);
newVal.setSum(old.getSum() + requestDataSize);
// we need to loop here if someone changed the value behind our back
} while (!countSumRef.compareAndSet(old, newVal));
这可确保您的计数和总和始终保持同步。如果您使用了两个AtomicLong
变量,则必须发出两个原子请求并且再次需要锁。
当你想重置这些值时,你会做同样的事情。
CountSum newVal = new CountSum(0, 0);
CountSum old;
do {
old = countSumRef.get();
// we need to loop here if someone changed the value behind our back
} while (!countSumRef.compareAndSet(old, newVal));
// now you can display the old value and be sure you got everything