悲观锁:
synchronized是独占锁(悲观锁)
其特点是
会导致其他所有需要锁的线程挂起,等待持有锁的线程释放资源
每次操作不加锁,假设没有冲去取完成某项操作
如果因为冲突导致失败则会重试到成功为止
乐观锁的实现--->这个思想就是CAS思想
方法:
三个值:
当前内存值V
旧的预期值A
将更新的值B
先获取到内存中当前的内存之V
将V与A比较
如果V和A相等,将B赋值给V并且返回true
否则什么都不做返回false
if(V == A){
V = B;
return true;
}else {
return false;
}
特点:
CAS是一组原子操作,不会被外部打断
属于硬件级别的操作(利用CPU的CAS指令,借助JNI来完成的非阻塞算法),效率比加锁操作高
ABA问题:
如果变量V初次读取的时候是A,准备赋值的时候检查也是A能否说明它没有被其他线程修改过?
如果这段期间曾经被改成B然后又改回A那么CAS操作会误认为它从来没有被修改过
通过日志查看操作来确定没有被动过--->C或C++实现原理
按照可沿用属性分类:
可重入锁
公平锁
不公平锁
(根据是否按照队列顺序进行操作来划分)
不可重入锁
自旋锁
两大核心值:
version--->1--->被更新以后的版本变为2
number-->10--->9更新的时候比较版本是否相同,版本相同更新,版本不同不更新。
比较并交换数据
package thread.rearrangement;
?
import java.util.concurrent.atomic.AtomicInteger;
?
/**
* CAS比较并交换
* @since JDk 1.8
* @date 2021/6/23
* @author Lucifer
*/
public class CAS {
?
/*先加入资源类对象*/
//库存对象
private static AtomicInteger stock = new AtomicInteger(5);
/*
Atomic原子性操作里面都会用到原子性的思想
里面用的不是synchronized同步锁
而是用CAS的思想,效率高,是硬件级别的操作
*/
?
public static void main(String[] args) {
?
/*利用lambda表达式开辟五个线程*/
for (int i=0; i<5; i++){
new Thread(() -> {
?
/*模拟延时*/
try {
Thread.sleep(1000);
}catch (InterruptedException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
?
/*抢购库存的数据,就是减少数据*/
Integer left = stock.decrementAndGet();
/*
这个方法的源码当中就存在CAS的思想
*/
?
/*判断*/
if (left<1){
System.out.println("抢完了...");
return;
}
?
/*打印出获取到资源的线程*/
System.out.println(Thread.currentThread().getName() + "抢了一件商品");
System.out.println("还剩" + left);
?
}).start();
}
}
?
}
原文:https://www.cnblogs.com/JunkingBoy/p/14923093.html