首页 > 编程知识 正文

cas底层实现原理,工厂类java

时间:2023-05-03 07:08:18 阅读:47296 作者:2234

一、什么是CAS?

比较交换(cas )。 这是CPU同时原语。 其功能是判断内存中某个位置的值是否为期望值,如果是,则更新为新值,这个过程是原子性的。

1公共类案例{

2 publicstaticvoidmain (字符串[ ] args ) {

3 atomicintegeratomicinteger=newatomicinteger (5;

4

5系统. out.print (atomic integer.compareandset (5,2019 ) );

6 system.out.println (' the value are ' atomic integer.get );

7

8系统. out.print (atomic integer.compareandset (5,1024 ) );

9 system.out.println (' the value are ' atomic integer.get );

10 }

11 }

CAS同时原语在Java语言中是sun.misc.Unsafe类的各个方法。 通过调用Unsafe类的CAS方法,JVM可以实现CAS程序集指令。 这是完全依赖硬件的功能,通过它实现了原子操作。 此外,由于CAS是系统原语,因此原语属于操作系统术语的范畴,是一个由若干指令组成、完成某些功能的过程,原语的执行必须是连续的,在执行过程中不允许中断。 也就是说,CAS是原子命令,不会引起数据不匹配的问题。

二. Unsafe类

以原子整合子原子类为例。

1 publicclassatomicintegerextendsnumberimplementsjava.io.serializable {

2保密长时间服务版本=6214790243416807050 l;

3

4//setuptouseunsafe.compareandswapintforupdates

5私密性staticfinalunsafeunsafe=unsafe.get unsafe (;

6隐私保护长时间服务;

7

8静态{

9特里{

10 value offset=unsafe.objectfieldoffset

11 ) atomic integer.class.getdeclaredfield (' value );

12 ) catch(exceptionex ) thrownewerror ) ex; }

13 }

14

15私有电压int value;

16

17/.

18 }

2.1参数分析

UnSafe是CAS的核心类。 Java方法无法直接访问基础,因此必须从本地(native )方法进行访问。 UnSafe相当于可以直接操作特定内存数据的后门。 Unsafe类位于sun.misc包中,Java cas操作的执行依赖于Unsafe类的方法,因此内部方法操作可以像c指针一样直接操作内存。

注意: Unsafe类的所有方法都是用native限定的。 也就是说,Unsafe类的方法直接调用基本资源来执行相应的任务。

变量valueOffset是该变量在内存中的偏移地址。 这是因为Unsafe从内存偏移地址获取数据。

变量value由volatile限定,以确保多线程之间的可见性。

2.2方法实例分析

例如,假设AtomicInteger原子类的getAndIncrement ()。

1 /**

2 *如何等效于2 * AtomicInteger.java类的自填充

3 */

4公共final int getandincrement (

5 return unsafe.getandaddint (this,valueOffset,1 );

6 }

7

获取8 //Unsafe类指定的内存区域变量的值

9 publicnativeintgetintvolatile (objectvar 1,long var2);

10

11

12 /**

13 * Unsafe类的方法

14 * @param var1当前AtomicInteger对象

15 * @param var2变量在内存中的偏移地址

16 * @param var4变量的增量

17 *方法分析:

18 *首先调用getIntVolatile ()方法获取指定内存区域的变量值并将其存储在var5中。

19 *在执行增值操作之前,请再次从此地址获取值,并将其与var5进行比较。

20 *如果相同,则更新var5的值并返回true,反转后退出循环并返回相加后的值;

21 *如果不相同,返回false,继续循环直到更新成功,然后重新获得值

2*/

23 publicfinalintgetandaddint (objectvar 1、long var2、int var4) {

24 int var5;

25 do {

26 var5=this.getint volatile (var 1,var2);

27 ) while (! this.compareandswapint(var1、var2、var5、var5 var4);

28

29返回Var 5;

30 }

三. CAS的缺点

3.1周期时间越长,开销越大

如果CAS无法获取值,则CPU会产生很大的开销。

3.2只能保证一个共有变量的原子性

操作多个共有变量时,循环CAS不能保证操作的原子性,但在这种情况下用锁可以保证原子性。

3.3 ABA问题

CAS算法实现的一个重要前提是,需要取出存储器中的某一时刻的数据,并与当前时刻进行比较进行替换,在该时间差内数据会发生变化。

例如,假设一个线程one从内存位置v中取出了a。 此时,另一个线程two也从内存中取出a。 然后,线程two执行一些操作以将值更改为b,线程two将v位置的数据更改为a。 此时,线程one进行了CAS操作,发现内存中还有a,线程one的操作成功。

线程one的CAS操作成功,但并不意味着此过程没有问题。

解决ABA问题的是Java.util.concurrent.atomic.atomicstampedreference; 用带时间戳的原子引用类解决。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。