我只是喜欢新玩具,而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处理器上运行基准测试。

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

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

  • 代码在这里可用

底线

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

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

  • 补充阅读– Brian Goetz关于Java并发性。

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

Java 8 LongAdders:管理并发计数器的正确方法相关推荐

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

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

  2. Java 的布局管理器GridBagLayout的使用方法【图文说明】

    GridBagLayout是java里面最重要的布局管理器之一,可以做出很复杂的布局,可以说GridBagLayout是必须要学好的的, GridBagLayout 类是一个灵活的布局管理器,它不要求 ...

  3. java jcombobox用法_java – 填充JComboBox的正确方法?

    我认为最干净的方法是定义自定义 ComboBoxModel. 这样,您可以为组合框定义数据模型,将创建组合框的部分与数据管理本身分开. 可能使用文本文件是一件好事,因为在插入新条目时您不必修改代码.您 ...

  4. Java并发编程(3):线程挂起、恢复与终止的正确方法(含代码)

    挂起和恢复线程 Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的.如果在不合适的时候挂起线程(比如,锁定共享资源时),此时 ...

  5. java并发计数器_浅谈java并发之计数器CountDownLatch

    CountDownLatch简介 CountDownLatch顾名思义,count + down + latch = 计数 + 减 + 门闩(这么拆分也是便于记忆=_=) 可以理解这个东西就是个计数器 ...

  6. Java多线程(五) —— 线程并发库之锁机制

    参考文献: http://www.blogjava.net/xylz/archive/2010/07/08/325587.html 一.Lock与ReentrantLock 前面的章节主要谈谈原子操作 ...

  7. 十分良心!全网最详细的Java 自动内存管理机制及性能优化教程

    同样的,先来个思维导图预览一下本文结构. 一图带你看完本文 一.运行时数据区域 首先来看看Java虚拟机所管理的内存包括哪些区域,就像我们要了解一个房子,我们得先知道这个房子大体构造.根据<Ja ...

  8. java ee api_Java EE并发API教程

    java ee api 这是一个示例章节,摘自Francesco Marchioni编辑的WildFly上的实用Java EE 7开发 . 本章讨论了新的Java EE并发API(JSR 236) , ...

  9. 【Java学习】JUC并发编程

    目录 1.JUC是什么 1.1 JUC简介 1.2 线程和进程概念 1.2.1 进程和线程 1.3 线程的状态 1.3.1 线程状态枚举类 1.3.2 wait和sleep的区别 1.3.3 使用范围 ...

最新文章

  1. php检查图片大小,如何利用Javascript函数检查图片大小
  2. windows 端微信多开
  3. mybais逆向工程快速生成实体和基本xml
  4. Flume Source
  5. 利用物联网技术为市民打造“无忧”生活
  6. idea错误提示不明显_淘宝镜像错误导致vue项目一系列异常
  7. 最新CleanMyMac支持MacOS 12.x
  8. Word文档多级标题自动编号设置
  9. 西部数据硬盘官网查询
  10. pdffactory字体打印不对_【原创】pdfFactory Pro有关转换PDG图像质量下降解决途径
  11. Unity -Shader精讲(一)OpenGL,DirectX,CG选择 着色器选择
  12. HDUOJ1234开门人和关门人
  13. python unrar问题_Python-使用unrar库时Couldn't find path to unrar library的解决办法
  14. 教养,就是要让别人舒服
  15. 豪能转债上市价格预测
  16. 请求示例curl获取电商商品详情数据API接口,批量采集
  17. LightningChart® JS BS端结合框架模拟心电图实例
  18. Chrome中的GPU加速合成
  19. C# Echarts 折线图 实例
  20. 程序员做了年收百万的副业

热门文章

  1. 双向链表的(CRUD)
  2. 学生用计算机说明方法,15.文中多处运用了作比较的说明方法.请任选一例.说说运用这种方法的作用. 例子: 作用:...
  3. Request获取参数封装方式
  4. 并发工具类【线程安全相关的类】
  5. junit4和junit5_JUnit5 TestSuite替代
  6. jmeter进行性能测试_使用JMeter进行性能测试
  7. spring框架介绍_Spring框架介绍
  8. spring http缓存_HTTP缓存与Spring示例
  9. Spring Boot和Apache Camel
  10. payara 创建 集群_使用Payara Micro的Easy Java EE Microservices