Java高效并发之乐观锁和悲观锁

悲观锁:
    每次拿数据都会加锁,Synchronized属于悲观锁[一段执行逻辑加上悲观锁,不同线程同时执行时,只能有一个线程执行,其他的线程在入口处等待,直到锁被释放]
乐观锁:
    一段执行逻辑加上乐观锁,不同线程同时执行时,可以同时进入执行,在最后更新数据的时候要检查这些数据是否被其他线程修改了(版本和执行初是否相同),没有修改则进行更新,否则放弃本次操作
    核心算法:CAS算法
        内存值、预期值、新值(首先检查某块内存的值是否跟之前我读取时的一样,如不一样则表示期间此内存值已经被别的线程更改过,舍弃本次操作,否则说明期间没有其他线程对此内存值操作,可以把新值设置给此块内存)
        如何保证CAS中的原子性:由CPU硬件指令实现[getAndIncrement中compareAndSet]

 1 public class AtomicInt {
 2             private volatile int value;
 3             public final int get() {
 4                 return value;
 5             }
 6 
 7             publicfinal int getAndIncrement() {
 8                 for (;;) {
 9                     int current = get();
10                     int next = current + 1;
11                     if (compareAndSet(current, next))
12                         return current;
13                 }
14             }
15 
16             public final boolean compareAndSet(int expect, int update) {
17                 //Unsafe类提供的硬件级别的compareAndSwapInt方法;
18             }
19         }

CAS存在ABA问题:假如内存值原来是A,后来被一条线程改为B,最后又被改成了A,则CAS认为此内存值并没有发生改变,但实际上是有被其他线程改过的

解决方法:解决的思路是引入版本号,每次变量更新都把版本号加一

在JDK18中进行了增强[unsafe.getAndAddInt]

public final int getAndIncrement() {
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

 

posted @ 2018-04-03 20:02  不是植物  阅读(166)  评论(0编辑  收藏  举报