mysql cas 更新_jdk与mysql的cas

全部过程有两个关键点:violate和本地原子操作

语录:

从内存领域来说这是乐观锁,因为它在对共享变量更新之前会先比较当前值是否与更新前的值一致,如果是,则更新,如果不是,则无限循环执行(称为自旋),直到当前值与更新前的值一致为止,才执行更新。

下面就分析一下:

先说violate,

AtomicInteger属性:

private volatile int value;

/**

* Creates a new AtomicInteger with the given initial value.

*

* @param initialValue the initial value

*/

public AtomicInteger(int initialValue) {

value = initialValue;

}

/**

* Creates a new AtomicInteger with initial value {@code 0}.

*/

public AtomicInteger() {

}

value是一个volatile变量,在内存中可见,任何线程都不允许对其进行拷贝,因此JVM可以保证任何时刻任何线程总能拿到该变量的最新值。

看看getAndIncrement()方法是怎么利用CAS实现的。

/**

* Atomically increments by one the current value.

*

* @return the previous value

*/

public final int getAndIncrement() {

return unsafe.getAndAddInt(this, valueOffset, 1);

}

此处调用unsafe 包的方法,将AtomicIntger对象和value的偏移量,用于底层硬件级别cas的取得value值,其功能相当于引用传递(如c语言实现)

public final int getAndAddInt(Object o, long offset, int delta) {

int v;

do {

v = getIntVolatile(o, offset);//------------0---------------

} while (!compareAndSwapInt(o, offset, v, v + delta));//-------------1-------------

return v;

}

此处首先取得value值  v,此值作为期望值,交给本地方法compareAndSwapInt,

/**

* Atomically update Java variable to x if it is currently

* holding expected.

* @return true if successful

*/

public final native boolean compareAndSwapInt(Object o, long offset,//---------------2--------------

int expected,

int x);

我稍微解释一下,其实compareAndSwapInt的注释解释的很明确,原子的将变量的值更新为x,如果成功了返回true,我们知道,如果我们创建AtomicInteger实例时不传入参数,则原始变量的值即为0,所以上面//----------0-----------处得到的v的值即为0,1处的代码为:

while(!compareAndSwapInt(o, offset, 0, 1))我们知道offset指向的地址对应的值就是原始变量的初值0,所以与期望的值0相同,所以将初值赋值为1,返回true,取反后为false,循环结束,返回v即更新之前的值0. 这就是类似于i++操作的原子操作的实现,当然最终CAS的实现都是native的,用C语言实现的,我们这里看不到源码,有时间我会反编译一下这段代码看看。

CAS线程安全

说了半天,我们要回归到最原始的问题了:这样怎么实现线程安全呢?请大家自己先考虑一下这个问题,其实我们在语言层面是没有做任何同步的操作的,大家也可以看到源码没有任何锁加在上面,可它为什么是线程安全的呢?这就是Atomic包下这些类的奥秘:语言层面不做处理,我们将其交给硬件—CPU和内存,利用CPU的多处理能力,实现硬件层面的阻塞,再加上volatile变量的特性即可实现基于原子操作的线程安全。所以说,CAS并不是无阻塞,只是阻塞并非在语言、线程方面,而是在硬件层面,所以无疑这样的操作会更快更高效!

其c语言实现为:

主要流程总结:

getvolatile                                              jdk  volatile关键字                   mysql rc隔离级别

do something

while {原子的compare and set}            jdk c++本地代码                    mysql db的原子性

get volatile jdk中表现为volatile关键字,即其它线程对共享变量的更新立即对本线程可见,mysql中表现为rc隔离级别,即其它事务的提交对本事务多次read操作可见,而不限于

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值