java - 线程安全的最终一致计数器
问题描述
我有一个高度并发的代码,应该能够同时增加\减少一些计数器并读取值。我不需要每次读取时的精确值,所以它可能最终是一致的。我的主要目标是写操作是非阻塞的并且不需要等待时间,基本上几个线程想要增加同一个计数器,调用一些增量函数并且不等待它被处理。但是,我很难找到制作这种计数器的方法。
我正在考虑使用ConcurrentLinkedQueue<Boolean>
. 将一个元素添加到队列中,并让另一个线程弹出元素并计算增量\减量。但是,这不是,BlockingQueue
所以我必须创建一个不断尝试轮询队列的线程,让一个线程完全致力于此任务感觉就像是一种巨大的浪费。仅仅请求size()
不是一种选择,因为ConcurrentLinkedQueue
操作不是恒定的时间,并且每次调用都必须遍历整个队列,这将是疯狂的浪费时间。
我也看过,AtomicInteger
但只有惰性设置操作,没有惰性增量,incrementAndGet
如果我理解正确会导致基于锁定的增量读取行为,这绝对不是我需要的。
使用ConcurrentLinkedQueue<Boolean>
专用轮询线程是最终一致计数器的唯一选择吗?特别是考虑到我不知道在任何时候有多少线程试图写入和读取这个计数器,这些是动态产生的。
解决方案
听起来java.util.concurrent.LongAdder可能是您正在寻找的:
当多个线程更新用于收集统计信息等目的的公共总和时,此类通常比 AtomicLong 更可取,而不是用于细粒度的同步控制。在低更新争用下,这两个类具有相似的特征。但是在高竞争下,这个类的预期吞吐量明显更高,代价是更高的空间消耗。
推荐阅读
- firebase - Firebase 云功能 - 在创建用户时写入数据库
- angular - 如何测试子组件的类属性?
- .net - 使用提琴手跟踪本地主机流量
- ag-grid - 是否可以使用 Ag-grid 图表库呈现仪表图表?
- javascript - 当用户点击输入字段时,我正在尝试禁用表单提交按钮
- django - 拥有数百万条记录的 Django 守护者
- reactjs - 在输入字段中隐藏部分文本
- java - 为什么我在 AmazonSQS 中收到 java.lang.NoClassDefFoundError?
- microsoft-graph-api - MS-Graph 和带附件的 sendmail 失败
- angular - 如何将 Ajax 获取请求转换为 Angular 7 http 获取请求