乐观锁和悲观锁
乐观锁AtomicInteger
public final int incrementAndGet() {
for (;;) {
//这里可以拿到value的最新值
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return next;
}
}
AtomicInteger这个变量存放在Java的内存堆里,当我在一个线程里要给它作增1操作时,发生的事情是:
1).首先从内存堆读取最新的变量,写到current变量中;
2).线程做next=current+1操作
3).写回主内存的AtomicInteger中时,有可能这个变量已经被其它变量修改,因此需要做compareAndSet,先比较后修改;
compareAndSet(current,next)的逻辑是首先判断内存中的值是否是current,如果是则改为next,它返回true表示修改成功
;
如果内存中的值不是current,那么表示这个变量已经被其它线程修改,此时不做修改操作,直接返回false
getAndIncrement实现的所有操作包在for(;;)这个无限循环中,直到修改成功。
这里实现的乐观锁机制的原理时,乐观的认为只有我一个线程进行修改,因此不需要加锁。如果有别人进行修改,那么我尝试多次修改达到增1的目的
悲观锁的原理时,我修改时,怕我的修改和别人的修改发生冲突,那么我不管有没有别人修改,我都强制加锁以保证修改不冲突
如果别人不修改,那么我加锁就是多余的了。
如果别人不修改,那么我加锁就是多余的了。
compareAndSet,就是乐观锁机制里面所谓的CAS原语,比较赋值是一个不可分割的原子操作,因此是线程安全的