首页 > 解决方案 > 线程安全的最终一致计数器

问题描述

我有一个高度并发的代码,应该能够同时增加\减少一些计数器并读取值。我不需要每次读取时的精确值,所以它可能最终是一致的。我的主要目标是写操作是非阻塞的并且不需要等待时间,基本上几个线程想要增加同一个计数器,调用一些增量函数并且不等待它被处理。但是,我很难找到制作这种计数器的方法。

我正在考虑使用ConcurrentLinkedQueue<Boolean>. 将一个元素添加到队列中,并让另一个线程弹出元素并计算增量\减量。但是,这不是,BlockingQueue所以我必须创建一个不断尝试轮询队列的线程,让一个线程完全致力于此任务感觉就像是一种巨大的浪费。仅仅请求size()不是一种选择,因为ConcurrentLinkedQueue操作不是恒定的时间,并且每次调用都必须遍历整个队列,这将是疯狂的浪费时间。

我也看过,AtomicInteger但只有惰性设置操作,没有惰性增量,incrementAndGet如果我理解正确会导致基于锁定的增量读取行为,这绝对不是我需要的。

使用ConcurrentLinkedQueue<Boolean>专用轮询线程是最终一致计数器的唯一选择吗?特别是考虑到我不知道在任何时候有多少线程试图写入和读取这个计数器,这些是动态产生的。

标签: javamultithreading

解决方案


听起来java.util.concurrent.LongAdder可能是您正在寻找的:

当多个线程更新用于收集统计信息等目的的公共总和时,此类通常比 AtomicLong 更可取,而不是用于细粒度的同步控制。在低更新争用下,这两个类具有相似的特征。但是在高竞争下,这个类的预期吞吐量明显更高,代价是更高的空间消耗。


推荐阅读