其他分享
首页 > 其他分享> > AtomicInteger如何保证线程安全以及乐观锁/悲观锁的概念

AtomicInteger如何保证线程安全以及乐观锁/悲观锁的概念

作者:互联网

众所周知,JDK提供了AtomicInteger保证对数字的操作是线程安全的,线程安全我首先想到了synchronized和Lock,但是这种方式又有一个名字,叫做互斥锁,一次只能有一个持有锁的线程进入,再加上还有不同线程争夺锁这个机制,效率比较低,所以又称“悲观锁”。

但是相应的有了乐观锁的概念,他的思路就是,它不加锁去完成某项操作,如果因为冲突失败就重试,直到成功为止。这种说的比较抽象,我们直接拿AtomicInteger源码举例,因为AtomicInteger保证线程安全就是因为使用了乐观锁。

Unsafe 是做一些Java语言不允许但是又十分有用的事情,具体的实现都是native方法,AtomicInteger里调用的 Unsafe 方法 基于的是CPU 的 CAS指令来实现的。所以基于 CAS 的操作可认为是无阻塞的,一个线程的失败或挂起不会引起其它线程也失败或挂起。并且由于 CAS 操作是 CPU 原语,所以性能比较好。

/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}

CAS就是Compare and Swap的意思,比较并操作。很多的cpu直接支持CAS指令。CAS是项乐观锁技术,当多个线程尝试使用CAS同时更新同一个变量时,只有其中一个线程能更新变量的值,而其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次尝试。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 从代码上我们可以看到do while语句,从而证实当更新出现冲突时,即失败时,它还会尝试更新。符合乐观锁的思想。

public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
var5 = this.getIntVolatile(var1, var2);
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

return var5;
}

最后比较一下 乐观锁/悲观锁的 区别

乐观锁适用于写比较少的情况下,即冲突比较少发生,这样可以省去了锁的开销,加大了系统的整个吞吐量。
但如果经常产生冲突,乐观锁 的重复尝试 反倒会降低了性能,所以这种情况下用悲观锁就比较合适。

原文链接:https://blog.csdn.net/lovejj1994/article/details/79116272

标签:var5,CAS,AtomicInteger,乐观,int,线程,悲观
来源: https://www.cnblogs.com/renjiaqi/p/14091998.html