AtomicInteger如何保证线程安全以及乐观锁/悲观锁的概念
Posted renjiaqi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
以上是关于AtomicInteger如何保证线程安全以及乐观锁/悲观锁的概念的主要内容,如果未能解决你的问题,请参考以下文章