当前位置: 首页 > news >正文

北京网站建设价钱河南省今天刚刚人事调整最新

北京网站建设价钱,河南省今天刚刚人事调整最新,市场调研公司的最主要职能是,微信小程序开发网站建设目录 前言 一、原子变量操作类(AtomicLong为例) 1. 前言 2. 实例 二、JDK 8新增的原子操作类LongAdder 三、LongAccumulator类原理探究 前言 JUC包提供了一系列的原子性操作类,这些类都是使用非阻塞算法CAS实现的,相比使用…

目录

前言

一、原子变量操作类(AtomicLong为例)

1. 前言

2. 实例

二、JDK 8新增的原子操作类LongAdder

三、LongAccumulator类原理探究


前言

JUC包提供了一系列的原子性操作类,这些类都是使用非阻塞算法CAS实现的,相比使用锁实现原子性操作这在性能上有很大提高。

由于原子性操作类的原理都大致相同,这里讲解最简单的AtomicLong类的实现原理以及JDK 8中新增的LongAdder和LongAccumulator

类的原理。有了这些基础,再去理解其他原子性操作类的实现就不会感到困难了。

一、原子变量操作类(AtomicLong为例)

1. 前言

JUC 并发包中包含有 AtomicInteger、AtomicLong 和 AtomicBoolean 等原子性操作类它们的原理类似,我们主要讲解 AtomicLong

类。

AtomicLong 是原子性递增或者递减类,其内部使用 Unsafe 来实现。

通过Unsafe.getUnsafe()方法获取到 Unsafe 类的实例,这里你可能会有疑问,为何能通过 Unsafe.getUnsafe()方法获取到 Unsafe 类的

实例?

其实这是因为 AtomicLong类也是在 rt.jar 包下面的,AtomicLong 类就是通过 BootStarp 类加载器进行加载的。

在没有原子类的情况下,实现计数器需要使用一定的同步措施,比如使用 synchronized 关键字等,但是这些都是阻塞算法,对性能有

一定损耗,而原子操作类都使用 CAS 非阻塞算法,性能更好。

但是在高并发情况下AtomicLong 还会存在性能问题。

JDK 8 提供了一个在高并发下性能更好的 LongAdder 类。

2. 实例

AtomicLong是原子性递增或者递减类,其内部使用Unsafe来实现,我们看下面的代码:

  • 代码(1)通过Unsafe.getUnsafe()方法获取到Unsafe类的实例,这里你可能会有疑问,为何能通过Unsafe.getUnsafe()方法获取到Unsafe类的实例?其实这是因为AtomicLong类也是在rt.jar包下面的,AtomicLong类就是通过BootStarp类加载器进行加载的。
  • 代码(5)中的value被声明为volatile的,这是为了在多线程下保证内存可见性,value是具体存放计数的变量。
  • 代码(2)(4)获取value变量在AtomicLong类中的偏移量。

下面重点看下AtomicLong中的主要函数:

递增和递减操作代码:

在如上代码内部都是通过调用Unsafe的getAndAddLong方法来实现操作,这个函数是个原子性操作,这里第一个参数是AtomicLong实

例的引用,第二个参数是value变量在AtomicLong中的偏移值,第三个参数是要设置的第二个变量的值。

boolean compareAndSet(long expect, long update)方法:

在内部调用了unsafe.compareAndSwapLong方法。

如果原子变量中的value值等于expect,则使用update值更新该值并返回true,否则返回false。

示例代码:多线程使用AtomicLong统计0的个数。

public class Atomic {// (10) 创建Long型原子计数器private static final AtomicLong atomicLong = new AtomicLong();// (11) 创建数据源private static final Integer[] arrayOne = new Integer[]{0, 1, 2, 3, 0, 5, 6, 0, 56, 0};private static final Integer[] arrayTwo = new Integer[]{10, 1, 2, 3, 0, 5, 6, 0, 56, 0};public static void main(String[] args) throws InterruptedException {//(12)线程one统计数组arrayOne中0的个数Thread threadOne = new Thread(() -> {int size = arrayOne.length;for (Integer integer : arrayOne) {if (integer == 0) {atomicLong.incrementAndGet();}}});//(13)线程two统计数组arrayTwo中0的个数Thread threadTwo = new Thread(() -> {int size = arrayTwo.length;for (Integer integer : arrayTwo) {if (integer == 0) {atomicLong.incrementAndGet();}}});// (14) 启动子线程threadOne.start();threadTwo.start();// (15) 等待线程执行完毕threadOne.join();threadTwo.join();System.out.println("arrayOne & arrayTwo 0 的个数是: " + atomicLong.get());}
}

运行结果:

如上代码中的两个线程各自统计自己所持数据中0的个数,每当找到一个0就会调用AtomicLong的原子性递增方法。

在没有原子类的情况下,实现计数器需要使用一定的同步措施,比如使用synchronized关键字等,但是这些都是阻塞算法,对性能有一定

损耗,而本章介绍的这些原子操作类都使用CAS非阻塞算法,性能更好。

但是在高并发情况下AtomicLong还会存在性能问题。

JDK 8提供了一个在高并发下性能更好的LongAdder类,下面我们来讲解这个类。

二、JDK 8新增的原子操作类LongAdder

AtomicLong通过CAS提供了非阻塞的原子性操作,相比使用阻塞算法的同步器来说它的性能已经很好了,但是JDK开发组并不满足于此。

使用AtomicLong时,在高并发下大量线程会同时去竞争更新同一个原子变量,但是由于同时只有一个线程的CAS操作会成功,这就造成

了大量线程竞争失败后,会通过无限循环不断进行自旋尝试CAS的操作,而这会白白浪费CPU资源。

因此JDK 8新增了一个原子性递增或者递减类LongAdder用来克服在高并发下使用AtomicLong的缺点。既然AtomicLong的性能瓶颈是由

于过多线程同时去竞争一个变量的更新而产生的,那么如果把一个变量分解为多个变量,让同样多的线程去竞争多个资源,是不是就解决

了性能问题?是的,LongAdder就是这个思路。下面通过图来理解两者设计的不同之处,如图所示。

使用LongAdder时,则是在内部维护多个Cell变量,每个Cell里面有一个初始值为0的long型变量,这样,在同等并发量的情况下,争夺单

个变量更新操作的线程量会减少,这变相地减少了争夺共享资源的并发量。另外,多个线程在争夺同一个Cell原子变量时如果失败了,它

并不是在当前Cell变量上一直自旋CAS重试,而是尝试在其他Cell的变量上进行CAS尝试,这个改变增加了当前线程重试CAS成功的可能

性。最后,在获取LongAdder当前值时,是把所有Cell变量的value值累加后再加上base返回的。

该类通过内部cells数组分担了高并发下多线程同时对一个原子变量进行更新时的竞争量,让多个线程可以同时对cells数组里面的元素进行

并行的更新操作。

另外,数组元素Cell使用@sun.misc.Contended注解进行修饰,这避免了cells数组内多个原子变量被放入同一个缓存行,也就是避免了

伪共享,这对性能也是一个提升。

三、LongAccumulator类原理探究

LongAdder类是LongAccumulator的一个特例,LongAccumulator比LongAdder的功能更强大。

例如下面的构造函数,其中accumulatorFunction是一个双目运算器接口,其根据输入的两个参数返回一个计算值,

identity则是LongAccumulator累加器的初始值。

上面提到,LongAdder其实是LongAccumulator的一个特例,调用LongAdder就相当于使用下面的方式调用LongAccumulator:

LongAccumulator相比于LongAdder,可以为累加器提供非0的初始值,后者只能提供默认的0值。另外,前者还可以指定累加规则,

比如不进行累加而进行相乘,只需要在构造LongAccumulator时传入自定义的双目运算器即可,后者则内置累加的规则。

http://www.yayakq.cn/news/976417/

相关文章:

  • 做一个电商网站步骤小程序文档
  • 网站的欢迎页怎么做移动应用开发专业介绍
  • 企业网站推广制作教程网站该怎么找
  • 昆明城乡和住房建设局网站山东省建设招标信息网站
  • 网站运营和推广网站开发技术孵化
  • c 2015 做网站赣榆网站建设
  • 泗水做网站ys178个人博客登录首页
  • 网站域名哪里买企业邮箱格式
  • 重庆渝北网站建设免费低代码开发平台
  • 品牌网站制作五华建设银行网站
  • 网站广告动图怎么做的简约创意logo设计免费生成
  • 还有哪些网站可以做H558同城成都网站建设名录
  • 鞍山做百度网站一年多少钱房屋装修流程步骤
  • 如何低成本做网站推广wordpress绑定二级域名插件
  • 春哥 响应式网站建设怎么用wordpress建手机网站
  • 用vs做html网站百度官方免费下载
  • 微网站建设最新报价德阳网站制作
  • 临沂网站建设技术托管ddns怎么做网站
  • 外贸网站运营推广环艺毕业设计代做网站
  • 企业网站管理系统cms源码下载做预算查价格的网站是哪个
  • 网站是怎么挣钱的网站分类导航代码
  • 要加强网站内容建设怎么用云虚拟主机建设网站
  • 长沙专业的网站建设企业网站做短信验证需要多少钱
  • 找网站公司制作网站郑州网站建设公司航迪软件怎么样
  • 网站后端开发语言wordpress 查看版本
  • 自己家开了一家装修公司怎么做装修网站微信开发者工具怎么打开文件
  • 网站推广应该怎么做记账公司
  • 做静态网站的步骤做电商有哪些网站
  • 抄袭网站案例做热血钓鱼网站
  • 创业网站平台排名网站内容页面怎么做外链