java 并发计数器_Java 8 LongAdders:管理并发计数器的正确方法

java 并发计数器

博客羊

我只是买了新玩具,而Java 8有很多 。 这次我想谈谈我的最爱之一-并发加法器。 这是一组新的类,用于管理由多个线程编写和读取的计数器。 新的API有望显着提高性能,同时仍使事情简单明了。

自从多核体系结构问世以来人们一直在管理并发计数器,让我们看一看迄今为止Java提供的一些选项以及与新API相比它们的性能。

计数器 –这种方法意味着您正在多个线程之间的常规对象或静态字段中进行写入/读取操作。 不幸的是,这有两个原因。 首先是在Java中,A + = B操作不是原子操作。 如果打开输出字节码,将至少看到四条指令-一个用于将堆中的字段值加载到线程堆栈中,第二个用于加载增量,第三个用于添加它们,第四个用于设置结果进入领域。

如果在同一个内存位置同时有多个线程同时执行此操作,则极有可能错过写操作,因为一个线程可以覆盖另一个线程的值(又称“读取-修改-写入”) 。 与此相关的还有另一个讨厌的角度,那就是价值的波动性。 下面的更多内容。

这是一个菜鸟错误,而且很难调试。 如果您确实遇到了在您的应用程序中执行此操作的任何人,我想请您帮个忙。 在数据库中搜索“ Tal Weiss”。 如果您在那里看到我–删除我的记录。 我会更安全的。

同步 -这是最基本的并发习惯用法,它在读取或写入值时会阻塞所有其他线程。 当它起作用时,这是将代码转换为DMV行的可靠方法。

RWLock –基本Java锁的这种稍微复杂的版本,使您可以区分更改了值并需要阻止其他线程的线程与仅读取且不需要关键部分的线程。 尽管这可能更有效(假设编写器的数量很低),但是这是一个相当不错的方法,因为在获取写锁时,您将阻止所有其他线程的执行。

易失性 -这个相当容易被误解的关键字实际上指示JIT编译器取消优化运行时机器代码,以便其他线程可以立即看到对该字段的任何修改。

这使一些JIT编译器最喜欢的优化工作失去了分配分配到内存的顺序。 再说一次 你听到了 JIT编译器可以更改对字段进行分配的顺序。 这种不可思议的小策略(也称为before-before )使它可以最小化程序访问全局堆所需的次数,同时仍确保您的代码不受其影响。 偷偷摸摸的…

那么,什么时候应该使用易失性计数器? 如果只有一个线程在更新一个值,而有多个线程在使用它,那么这是一个非常好的策略–根本没有争用。

那么为什么不总是问它呢? 因为当一个以上的线程正在更新该字段时,这不能很好地工作。 由于A + = B不是原子的,因此存在覆盖其他人的写入的风险。 在Java 8之前,您需要使用AtomicInteger。

AtomicInteger-这组类使用CAS(比较和交换)处理器指令来更新计数器的值。 听起来不错,不是吗? 好吧,是的,不是。 这很有效,因为它利用直接的机器代码指令来设置该值,而对其他线程的执行影响最小。 缺点是,如果由于与另一个线程的争用而无法设置该值,则必须重试。 在竞争激烈的情况下,这可能会变成自旋锁,其中线程必须不断尝试并在无限循环中设置该值,直到成功为止。 这不是我们想要的。 输入带有LongAdders的Java 8。

Java 8 Adders –这是一个非常酷的新API,我永不过时! 从使用角度来看,它与AtomicInteger非常相似。 只需创建一个LongAdder并使用intValue()和add()即可获取/设置值。 魔术发生在幕后。

此类的作用是,当直接CAS由于争用而失败时,它将增量存储在为该线程分配的内部单元对象中。 然后在调用intValue()时将待处理单元格的值加到总和上。 这减少了返回和CAS或阻止其他线程的需要。 很聪明的东西!

这么好说吧-让我们看看这只小狗在行动。 我们建立了以下基准:将计数器重置为零,并开始使用多个线程读取和递增计数器。 当计数器达到10 ^ 8时停止。 我们在4核i7处理器上运行了基准测试。

我们使用总共十个线程来运行基准测试-五个用于写作,五个用于阅读,因此我们在这里势必会引起严重的争论:

  • 请注意,肮脏和易变的风险值都将覆盖。

table_april-16_02-2

底线

  • 并发加法器洁净室的性能比原子整数提高60-100%
  • 除了锁定时,添加线程没有什么区别。
  • 请注意,使用同步锁或RW锁会给您带来巨大的性能损失-慢一个数量级!

如果您已经有机会在代码中使用这些类,那么我很乐意听到。

翻译自: https://www.javacodegeeks.com/2014/04/java-8-longadders-the-right-way-to-manage-concurrent-counters.html

java 并发计数器

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值