1. 首页 > 快讯

JAVA基础——并发编程之原子类

每天进步一点点,大家好,我是大龄码农。我们今天讲解concurrent包的另一个子包atomic,这个包中都是原子类以及原子操作类。原子类以及原子操作就可以解决++这种非原子操作可能导致的线程同步问题在讲解volatile时说过,它只具有可见性,但不具有原子性,对于多线程中的++操作,必须使用关键字synchronized来保证线程同步,这种阻塞同步是一种悲观的并发策略。相对地,还有一种非阻塞同步的乐观并发策略,顾名思义,就是很乐观地认为别人不会和我抢,所以不加锁,只有在最后更新时才会判断。此时如果操作失败也不会阻塞,它会采取一些补偿机制,一般就是反复重试。在讲原子类之前,先介绍下Unsafe类,因为原子类的操作都是基于该类做的。Unsafe对象提供了非常底层操作内存和线程的方法,该类只提供了一个私有的无参构造方法。通过getUnsafe()静态方法获得Unsafe对象,然后调用它的CAS操作说明:我们在程序中无法直接调用,会抛出异常CAS是Compare And Swap的缩写,是比较并交换的意思,它是这样一种原子操作:针对一个变量,首先比较它的内存值与某个期望值是否相同,如果相同,就给它赋一个新值。
  • CAS是一个不可分割的原子操作,并且其原子性是直接在硬件层面得到保障的。
  • CAS是乐观锁的一种实现方式
  • CAS是一种无锁算法,在没有线程被阻塞的情况下实现多线程之间的变量同步。
CAS 操作是由Unsafe类提供支持的,定义了三种针对不同类型变量的CAS操作,它们都是native方法,由Java虚拟机提供具体实现。以compareAndSwapInt为例,该方法提供四个参数:对象实例、内存偏移量、字段期望值、字段新值。该方法会针对指定对象实例中的相应偏移量的字段执行CAS操作。基础的知识讲完了,我们现在开始讲解原子类,由于atomic子包中的原子类的实现机理很类似,我们就挑选几个典型的原子类来进行分析。AtomicInteger的原子类型自增

说明:使用的都是native方法,如果只通过名字猜,估计也能知道getIntVolatile()是获取内存中最新的值,只要compareAndSwapInt()方法不成功,就一直反复尝试直到成功。其他功能基本类似就不再重复了。

AtomicIntegerFieldUpdater可以对普通变量进行升级
  • 这个普通变量,只是偶尔需要一个原子get/set操作
  • 这个变量是其他人定义的,我们无权将他定义为原子类型,只能对他进行临时升级
说明:1、通过包装后,可以使得变量的操作是线程安全的2、被升级的变量有两个限制:
  • 不支持被static修饰的变量
  • 可见范围,由public修饰的变量,private不行
LongAdder累加器
  • Java8引入
  • 高并发下LongAdder比AtomicLong效率高,本质还是空间换时间
  • 竞争激烈的情况下,LongAdder会把不同线程对应到不同的Cell上进行修改,降低冲突的概率,是多段锁的理念,提高了并发性
Accumulator累加器Accumulator 就是一个更通用版本的 Adder,提供了自定义的函数操作。综上,相比锁机制,使用原子类更精巧轻量,性能开销更小。不过底层CAS仍然存在以下缺点:
  • 循环长时间不成功会给CPU带来非常大的开销
  • ABA问题
ABA问题CAS算法是取出内存中某时刻的数据,和当下时刻的数据比较并替换,但是如果在这个时间内数据已经发生了变化但是线程无法感知会怎么处理?举个例子,当多个线程对一个原子类进行操作时,某个线程在短时间内将原子类的值A修改为B,又马上将其修改为A,此时其他线程是感知不到的,还是会修改成功。解决方案数据库有个锁称为乐观锁,是一种基于数据版本实现数据同步的机制,每次修改一次数据,版本就会进行累加。Java也提供了相应的原子引用类AtomicStampedReference。说明:stamp是版本,每次修改可以通过+1保证版本唯一性。这样就可以保证每次修改后的版本也会往上递增
实践一、Unsafe通过反射获取Unsafe对象定义一个测试对象定义Unsafe的操作方法测试类说明:1、通过底层方法compareAndSwapInt()更新字段的值2、调用系统提供的方法获取Unsafe时,不出意外地抛出异常二、ABA说明:使用版本控制可以解决ABA的问题三、自定义锁知道了原子类的底层实现方法,我们可以模仿创建一个自己的锁

测试结果如下

其他常用的方法简单看下API就行,不难理解。总结:1、介绍了原子类的基本知识2、介绍了原子类实现的底层知识3、用程序讲解了一些常用原子类的主要方法
希望大家一定要动手做一做,自己验证一下。需要代码的朋友,可以留下邮箱。

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:https://www.iotsj.com//kuaixun/3293.html

联系我们

在线咨询:点击这里给我发消息

微信号:666666