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

博客羊

我只是喜欢新玩具,而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锁会给您带来巨大的性能损失-慢一个数量级!

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364132.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JS中ptototype和__proto__的关系

学到原型的时候感觉头都大了/(ㄒoㄒ)/~~ 尤其是ptototype和__proto__ 傻傻分不清 通过多番查找资料,根据自己的理解,总结如下: 一、构造函数: 构造函数:通过new关键字可以用来创建特定类型的对象的函数。比如像Obje…

[最短路]飞行

题目描述 WFYZ的校园很大,这里生活着很多生物,比如住在钟楼上的的鸽子,其中鸽子冉冉和她的妹妹凝凝白天在不同的地方吃虫,而在晚上她们都回到钟楼休息。她俩是两只懒鸟,于是提出了一个计划,尽量减少她们在飞…

Java状态和策略设计模式之间的差异

为了在Core Java应用程序中正确使用状态和策略设计模式,对于Java开发人员清楚地了解它们之间的区别很重要。 尽管状态和策略设计模式的结构相似,并且都基于开放式封闭设计原则,从SOLID设计原则表示为“ O”,但它们在意图上完全不同…

廖雪峰Java3异常处理-1错误处理-2捕获异常

1捕获异常 1.1 finally语句保证有无错误都会执行 try{...}catch (){...}finally{...} 使用try...catch捕获异常可能发生异常的语句放在try{...}中使用catch捕获对应的Exception及其子类1.2 捕获多个异常 try{...} catch() {...} catch(){...}finally{..} 使用多个catch子句&…

更新数据库

方法一:在对SQL数据库进行更新时,用CommandBuilder对像来自动构建sql命令,来起到更新的作用;这种方法用起来比较方便,具体代码如下: 以下代码都在xp系统下测试通过 环境:vs.net2005 \ sql server 2000\xpus…

在崩溃或断电后测试Lucene的索引耐久性

Lucene有用的事务功能之一是索引持久性 ,它可以确保一旦成功调用IndexWriter.commit ,即使操作系统或JVM崩溃或断电,或者您杀死-KILL JVM进程,重启后索引也将保持完整(未损坏),并将反映崩溃前的…

Jmeter、postman、python 三大主流技术如何操作数据库?

1、前言 只要是做测试工作的,必然会接触到数据库,数据库在工作中的主要应用场景包括但不限于以下: 功能测试中,涉及数据展示功能,需查库校验数据正确及完整性;例如商品搜索功能 自动化测试或性能测试中&a…

利用ASP.NET向服务器上传文件[转]

文件上传技术是一个很实用的技术,有着很广泛的应用,在ASP.NET自身的前一个版本ASP里实现这个功能,就必须使用第三方的组件或者自己开发组件了,现在,用ASP.NET实现起来就简单得多了,我们不需要使用任何组件就…

java中HashMap详解

HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员,其中 HashMap 是 Map 接口的常用实现类,HashSet 是 Set 接口的常用实现类。虽然 HashMap 和 HashSet 实现的接口规范不同,但它们底层的 Hash 存储机制完全一样,甚…

java代码编写的文本特征提取_Test1 java语言写的特征提取源代码,有搞文字识别的可以下载一看,简单易学 Develop 274万源代码下载- www.pudn.com...

文件名称: Test1下载 收藏√ [5 4 3 2 1 ]开发工具: Java文件大小: 35 KB上传时间: 2015-03-02下载次数: 46提 供 者: 常杰详细说明:java语言写的特征提取源代码,有搞文字识别的可以下载一看,简单易学-Feature extraction of the Java …

c# HashTable (哈希表)

HashTable 哈希表 也是System.Collections集合下的数据结构类 它储存的也是Object类型的对象 但是它在内存中是散列排布的 因为这个特性,非常适合存储大量的数据 在HashTable中一个键只能对应一个值,一个值可以对应多个键(多对一)…

Spring集成–配置Web服务客户端超时

介绍 在Spring Integration的支持下,您的应用程序可以使用出站Web服务网关来调用Web服务。 调用由该网关处理,因此您只需要担心构建请求消息和处理响应。 但是,使用这种方法并不明显,如何配置其他选项,例如设置超时或操…

将txt文件和excel文件导入SQL2000数据库

在做一些web数据库管理系统的时候经常要实现将帐户批量注册的功能,今天就来讲讲如何在C#-web项目中将txt文件和excel文件导入SQL2000数据库。1.数据库准备在SQL2000数据库的实例数据库pubs中建立一个数据表txtInsert,字段很简单:id&#xff0…

Java 8 Friday:Java 8将彻底改变数据库访问

在Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 对于Java 8系列 ,我们很荣幸主持Iu Ming-Yee Iu博士发表的非常相关的嘉宾帖子。 Iu …

Linux文件权限管理

权限管理 1、权限解读 权限:用户针对文件是否有读、写、执行的权利。 权限划分:读(Read)、写(Write)、执行(eXecute) 权限针对用户的划分:主人(User&#xff…

Sqoop数据迁移工具的使用

文章作者:foochane 原文链接:https://foochane.cn/article/2019063001.html Sqoop数据迁移工具的使用 sqoop简单介绍 sqoop数据到HDFS/HIVE sqoop数据到MySQL 1 sqoop简单介绍 sqoop是apache旗下一款“Hadoop和关系数据库服务器之间传送数据”的工具。用…

java中io.nio.aio_Java中网络IO的实现方式-BIO、NIO、AIO

在网络编程中,接触到最多的就是利用Socket进行网络通信开发。在Java中主要是以下三种实现方式BIO、NIO、AIO。关于这三个概念的辨析以前一直都是好像懂,但是表达的不是很清楚,下面做个总结完全辨析清楚。1. BIO方式首先我用一个较为通俗的语言…

C++中this指针

由类生成对象时&#xff0c;对象中只保存私有数据。 因为由一个类生成的所有对象为其数据服务的方法都是相同的&#xff0c;因此&#xff0c;一个类中的方法是大家所共用的。 而这就牵扯到当对象A调用方法时&#xff0c;如何保证该方法操作的数据是对象A的数据。 #include<i…

jfinal java搭建_Eclipse快速搭建Jfinal web应用 (一)

JFinal简介JFinal 是基于 Java 语言的极速 WEB ORM 框架&#xff0c;其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率&#xff01;为您节约更多时间&#xff0c…

PHP后台处理jQuery Ajax跨域请求问题 — xx was not called解决办法

// 前台代码 $.ajax({url: http://www.ushark.net/home/save_trial_apply,dataType: jsonp,processData: false,data: $(.layui-layer-content #trialFormInfo).serialize(), }) .done(function(data) {layer.msg(申请成功); }) .fail(function(jqXHR, textStatus, errorThrown…