CAS、ABA问题以及UnSafe类

CAS

1、什么是CAS?

CAS:Compare and Swap,即比较再交换。

jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是悲观锁

ABA

假设这里有两个线程线程1和线程2,线程1工作时间需要10秒,线程2工作需要2秒,主内存值为A,第一轮线程1和线程2都把A拿到自己的工作内存,2秒中后线程2工作完成把A改成了B再写回去,又过了2秒,线程2把B改成了A再写回去,然后就线程2进入休眠状态,这时候线程1工作完成,看到期望为A真实值也是A认为没有人动过,然后线程1进行CAS操作。尽管线程1的CAS操作成功,但是不代表这个过程就是没问题的。

ABA问题的解决

新增一种机制,那就是修改版本号(类似于时间戳)。

用AtomicStampedReference(int initialRef, int initialStamp),它有两个参数,第一个初始值,第二是初始版本号,它的compareAndSet方法有四个参数:

UnSafe

Java无法直接访问底层操作系统,而是通过本地(native)方法来访问。不过尽管如此,JVM还是开了一个后门,JDK中有一个类Unsafe,它提供了硬件级别的原子操作。

这个类尽管里面的方法都是public的,但是并没有办法使用它们,JDK API文档也没有提供任何关于这个类的方法的解释。总而言之,对于Unsafe类的使用都是受限制的,只有授信的代码才能获得该类的实例,当然JDK库里面的类是可以随意使用的。

Unsafe提供了硬件级别的操作,比如说获取某个属性在内存中的位置,比如说修改对象的字段值,即使它是私有的。不过Java本身就是为了屏蔽底层的差异,对于一般的开发而言也很少会有这样的需求。

//方法可以用来获取给定的f的内存地址偏移量,这个值对于给定的field是唯一的且是固定不变的。
private native long staticFieldOffset0(Field f);
//获取数组第一个元素的偏移地址
private native int arrayBaseOffset0(Class<?> arrayClass);
//获取数组的转换因子即数组中元素的增量地址的
private native int arrayIndexScale0(Class<?> arrayClass);

//下面三个方法
private native long allocateMemory0(long bytes);//分配内存
private native long reallocateMemory0(long address, long bytes);//扩充内存
private native void freeMemory0(long address);//释放内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值