首页 国际新闻正文

上错花轿嫁对郎,“全栈2019”Java原子操作第十四章:高性能高效率的原子类介绍,金山

难度

初级

学习时刻

30分钟

合适人群

零根底

开发言语

Java

开发环境

  • JDK v11
  • IntelliJIDEA v2018.3

友谊提示

  • 本教育归于系列教育,内容具有连贯性,本章运用到的内容之前教育中都有详细解说。
  • 本章内容针对零根底或根底较差的同学比较友爱,或许关于有根底的同学来说很简略,期望咱们能够依据自己的实际状况挑选继续看完或等候看下一篇文章。谢谢咱们的体谅!

1.温故知新

前面在《“全栈2019”Java原子操作第九章:atomic包下原子数组介绍与运用》一章中介绍了什么是原子数组AtomicIntegerArray、AtomicLongArray和AtomicReferenceArray

《“全栈2019”Java原子操作第十章:atomic包下字段原子更新器介绍》一章中介绍了什么是字段原子更新器AtomicIntegerFieldUpdater、AtomicLongFieldUpdater和AtomicReferenceFieldUpdater

《“全栈2019”Java原子操作第十一章:CAS与ABA问题介绍与讨论》一章中介绍了CAS算法中存在的ABA问题

《“全栈2019”Java原子操作第十二章:AtomicStampedReference详解》一章中介绍了什么是带版本号的原子类AtomicStampedReference

《“全栈2019”Java原子操作第十三章:AtomicMarkableRe张藤子ference类》一章中介绍了什么是带修正符号的原子类AtomicMarkableReference

现在介绍高功能高功率的原子类DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder

2.既生瑜何生亮?

本系列的第四章至第十三章将Java8之前供给的原子类都已介绍过,Java8又供给了4个原子操作类:

  • DoubleAccumulator // double类型高功能二元运算原子类
  • DoubleAdder // double类型高功能求和原子类
  • LongAccumulator // long类型高功能二元运算原子类
  • LongAdder // long类型高功能求和原子类

这4个类除了功用和类型有点不同以外,内部完结多为相同。

拿LongAdder来说,已然有了AtomicLong,为何还要推出LongAdder?

尽管AtomicLong内部和LongAdder内部都调用了底层完结CAS算法的办法,可是AtomicLong工作办法与LongAdder工作办法不同。

AtomicLong工作办法是多个线程操作同一个变量

而LongAdder工作办法则将上述状况进行了改善,LongAdder做两手预备:高并发状况和非高并发状况

针对这两种状况,LongAdder类别离预备了两个变量来应对:long base和Cell[] cells。

非高并发状况下,操作base变量,终究成果便是base的值:

高并发状况下,操作base和cells数组,终究成果便是将base变量的值和cells上错花轿嫁对郎,“全栈2019”Java原子操作第十四章:高功能高功率的原子类介绍,金山数组里边的Cell目标的值相加:

base:用volatile关键字润饰的一般的long类型变量。

cells:用volatile关键字润饰的Cell数组。

Cell类:

类中保护了一个存储值的value变量和一个内部调用底层完结CAS算法的cas办法。

每一个Cell目标里边都能够存储值和调用CAS办法。

3.简略的递加

经过一个程序体会一般long类型->AtomicLong->LongAdder的改变进程。

往往程序中一个小小的核算操作,就隐藏着无限大的问题。

下面是一段递加变量value的程序。

首要,定义出变量value:

然后,创立出递加使命:

在任谭茜小三务run()办法中递加value并输出:

run()办法书写结束。

接下来,循环创立10个线程并履行递加使命:

这一步是模仿并发操作。

比如书写结束。

运转程序,履行成果:

从运转成果来看,契合预期。没有问题,value从0输出到9。

这时,咱们对程序稍加改动,使每个线程在递加前睡100毫秒(模仿推迟)

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。改动过的程序呈现问题,输出中呈现多个相同值,这是多个线程间数据不一起形成的。(详细原因及处理方案请看《“全栈2019”Java原子操作第二章:i++是原子操作吗?何为原子性》一章)

所以,你会将参加核算的部分同步重生之婚前停步起来:

比如改写结束。

运转程toptoon漫画序,履行成果:

从运转成果来看,问题得到处理。

同步尽管处理了咱们的问题,可是它也会带来其他问题,如:

  • 功率上,爱乐活蔡虎多个线程状况下,某一时刻最多只能有一个线程持有锁,其他线程被堵塞。这不光是功率问题,并且仍是在糟蹋线程资源。
  • 发作死锁的危险。

不同步就意味着程序会发生数申必达据一起性问题。

为处理无锁状况下的数据一起性问题,Java供给了CAS处理方案上错花轿嫁对郎,“全栈2019”Java原子操作第十四章:高功能高功率的原子类介绍,金山(详细请查阅《“全栈2019”Java原子操作第三章:比较并沟通CAS技能详解》一章)。

根据CAS算法,小明看以原子办法更新变量的原子类呼之欲出,在并发界大放异彩。

总共发生12个原子类:

  • AtomicBoolean
  • AtomicInteger
  • AtomicIntegerArray
  • Ato赵景强micIntegerFieldUpdater
  • AtomicLong
  • AtomicLongArray
  • AtomicLongFieldUpdater
  • AtomicMarkableReference
  • AtomicReference
  • AtomicReferenceArray
  • AtomicReferenceFieldUpdater
  • AtomicStampedReference

这12个原子类在之前的文章悉数介绍过,有需求的小伙伴请去作者主页查阅。

下面,咱们就取其间的AtomicLong原子类来处理比如中的问题。

4.原子类

仍是上一末节比如,只不过将同步代码块移除:

然后,将long类型换成Atomi刘涛肩带cLong类型:

由于long类型被换成AtomicLong类型,之前的“value++”写法需求作出调整:

“value.getAndIncrement()”与“value++”作用是相同的,写法上不同罢了。

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预牛仔裤引诱期。

同样是递加,同样是无锁,将根本类型long换成原子类AtomicLong类型,成果却天壤之别。

原子类带给咱们的优点是用非堵塞办法去处理并发问题。

5.精雕细镂,高功能求和类

为了更高效的运算,在CAS算法的根底上,再创光辉,诞生了高功能求和类:LongAdder和DoubleAdder。

Lon上错花轿嫁对郎,“全栈2019”Java原子操作第十四章:高功能高功率的原子类介绍,金山gAdder是一个long类型的高功能求和原子类。

  • LongAdder() // LongAdder无参结构办法
  • voidadd​(long x) // 添加指定值。
  • voiddecrement() // 递减。相当于add(-1)办法。
  • voidincrement() // 递加。相当于add(1)办法。
  • voidreset() // 将值重置为0。
  • longsum() // 回来当时和。
  • longsumThenReset() // 回来当时和并将值重置为0。

DoubleAdder是洗铜水一个double类型的高功能求和原子类。

  • DoubleAdder() // DoubleAdder无参结构办法
  • voidadd​(double x) // 添加指定值。
  • voidreset() // 将值重置为0。
  • longsum() // 回来当时和。
  • lon看护香香公主gsumThenReset() // 回来当时和并将值重置为0。

现在,Java只供给了这两个求和原子类。

注:LongAdder和DoubleAdder都不能指定初始值!

下面,咱们用LongAdder类去比如中试一试。

仍是上一末节比如,将AtomicLong类型换成徐天官LongAdder类型:

由于AtomicLong类型被换成LongAdder类型,之前的“value.getAndIncrement()”写法需蛙呼蛙呼要作出调整:

由于LongAdder目标的increment()办法不回来递加后的成果,所以咱们需求将递加和获取递加后的成果分两步来做。

increment()办法担任递加,sum()办法担任获取当时值的成果。

比如改写结束。

运转程序,履行成果:

从运转成果来看,契合预期。之所以打印成果不是0-9,是由于LongAdder目标的increment()办法相当于++1作用,并且递加和获取值分了两步,故在获取值之前值已递加完结,打印1-10。

6.AtomicLong与LongAdder功能比照

鉴于AtomicLong和LongAdder都需求很多核算,并且还要核算它们的耗时状况,所以咱们采纳线程池和有回来值的使命来辅佐此次演示。

首要,创立出AtomicLong类型变泪与千年量:

然后,创立出LongAdder类型变量:

接着,模仿在高并发状况下测验功能,创立线程池:

然后,创立出办理履行使命的服务:

接下来,咱们在main()办法中首要获取使命开端前的时刻:

然后,循环提交需求履行的使命(即把要履行的代码写在call()办法里边)木姜菜。

循环的次数便是线程池里边的线程的个数。

提交使命的办法便是completionService目标调用其submit(Callable task)办法:

接着,在call()办法里边写上递加使命。

这儿先测验AtomicLong类型变量,然后再测验LongAdder类型变量。

之所以写循环递加,是由于要模仿出核算量大,使命深重的状况:

循环提交使命结束。

接下来便是循环获取使命履行完结后的成果:

completionService.take()的作用是检索并移除表明下一个已完结使命的Future。

future.get()的作用是获取已完结使命的成果。

接下来,是核算耗时:

终究,封闭线程池:

比如书写结束。

运转程序,履行成果:

从运转成果来看,AtomicLong类型变量完结这一递加使命耗时1921毫秒。

下面,再来看看LongAdder类型。

将比如中递加使命中的AtomicLong变量换成LongAdder变量:

比如改写完结。

运转程序,履行成果:

从运转成果来看,LongAdder类型变量完结这一递加使命耗时173毫秒。

AtomicLong=》1921毫秒。

LongAdder=》173毫秒。

两者距离一望而知。

下一章为咱们揭开高功能原子类的隐秘。

7.DoubleA上错花轿嫁对郎,“全栈2019”Java原子操作第十四章:高功能高功率的原子类介绍,金山ccumulator类和LongAccumulator类常用办法

DoubleAccumulator类:

  • vo佛利民idaccumulate​(double x) // 与指定参数进行二元运算。
  • doubleget() // 回来当时值。
  • doublegetThenReset() // 回来当时值并重置。
  • voidreset() // 重置值。

LongAccumulator类:

  • voidaccumulate​(long x) // 与指定参数进行二元运算。
  • longget() // 回来当时值。
  • longgetThenReset() // 回来当时值并重置。
  • voidreset() 上错花轿嫁对郎,“全栈2019”Java原子操作第十四章:高功能高功率的原子类介绍,金山// 重置值。

DoubleAccumulator类和LongAccumulator类和LongAdder类操作办法相似这儿就不再演示,请体谅,如需演示请在谈论区留言,谢谢。

终究,期望咱们能够把这个比如照着写一遍,然后再自己默写一遍,便利今后碰到相似的面试题能够轻松应对。

祝咱们编码愉快!

GitHub

本章程序GitHub地址:https://github.com/gorhaf/Java2019/tree/master/Thread/atomic/高功能原子类

总结

  • DoubleAccumulator是一个double类型高功能二元运算原上错花轿嫁对郎,“全栈2019”Java原子操作第十四章:高功能高功率的原子类介绍,金山子类。
  • DoubleAdder刘泓君是一个double类型高功能求和原子类。
  • LongAccumulator是一个long类型高功能二元运算原子类。
  • LongAdder是一个long类型高功能求和原子类。
  • AtomicLong工作办法是多个线程操作同一个变量。
  • LongAdder工作办法则将上述状况进行了铁血之最强兵神何天龙改善,LongAdder做两手预备:高并发状况和非高并发状况。
  • 针对这两种状况,LongAdder类别离预备了两个变量来应对:long base和Cell[] cells。
  • 非高并发状况下,操作base变量,终究成果便是base的值。
  • 高并发状况下,操作base和cells数组,终究成果便是将base变量的值和cells数组里边的Cell目标的值相加。
  • Cell类中保护了一个存储值的value变量和一个内部调用底层完结CAS算法的cas办法。

至此,Java中DoubleAccumulator、DoubleAdder、LongAccumulator、LongAdder相关内容解说先告一段落,更多内容请继续重视。

答疑

假如咱们有问题或想了解更多前沿技能,请在下方留言或谈论,我会为咱们回答。

上一章

“全栈2019”Java原子操作第十三章:AtomicMarka上错花轿嫁对郎,“全栈2019”Java原子操作第十四章:高功能高功率的原子类介绍,金山bleReference类

下一章

“全栈2019”Java原子操作第十五章:高功能原子类是怎么完结的?

学习小组

参加同步学习小组,一起沟通与前进。

  • 办法一:重视头条号Gorhaf,私信“Java学习小组”。
  • 办法二:重视大众号Gorhaf,回复“Java学习小组”。

全栈工程师学习方案

重视咱们,参加“全栈工程师学习方案”。

版权声明

原创不易,未经答应不得转载!

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。