java 并发编程 - 显示锁和CAS

1. 显示锁 Lock

lock 接口可以提供一些sychnoized 不具备的一些其他特性 如:
1。 尝试非阻塞去获取锁
2. 可以被终端的获取锁
3. 超时获取锁
lock 接口的核心方法
lock():获取锁, 类似sychnonized 关键字
unlock():释放锁(当退出synchnonized 关键字所包围的代码块的时候, 锁自动释放)
tryLock(): 尝试非阻塞的去获取锁, 获得锁返回true, 没有返回false
显示锁的使用方法
Lock lock = new ReentranLock()
lock.lock()
try{
do sth…
}finally{
lock.unlock();
}

2. 排它锁

排它锁在同一时刻只允许一个线程访问

3. 读写锁

ReadWriteLock lock = new ReentrantReadWriteLock()
Lock getLock = lock.readLock()// 读锁
Lock setLock = lock.writeLock()// 读锁
代码示例:

在这里插入图片描述

在这里插入图片描述
比synchnonized 锁更快
在这里插入图片描述

4. Condition 接口

lock 接口不能和wait notify 等方法相结合实现等待。 所以有了condition 接口实现等待和通知

使用方法:
Lock kmlock= new ReentrantReadWriteLock()
Condition kmcond= kmlock.newCondition();
kmcond.signal(); kmcond.signalAll(); 通知其他在锁上等待的线程。 尽量使用signal, 因为知道是哪个锁, 只通知这个锁上的线程即可
kmcond.await()// 当前线程进行等待

代码示例:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5. CAS (Compare And Swap)操作:

比较并且交换。 三个运算符: 一个内存地址v, 一个期望的旧值A, 一个新值B
检查内存地址V 上的值, 是不是期望的A 值, 如果是, 就把地址v的变成B, 如果不是A , 则V 的值不变

CAS 带来的问题:

  1. ABA : 地址V 的值从 A–》C–>A 时, 我们检查的时候, 发现A-A 没有变, 但实际上C 已经过去了, 它的值已经变了, 不是原来的A 了
    解决: 版本号:1A–》2C–>3A 来控制

在这里插入图片描述
使用AtomicStampedReference 自带版本戳原子操作类
示例代码:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2. 循环时间长, 开销大
3. 往往只能保证一个共享变量的原子操作

示例代码:
ai.getAndIncrement(), get 在前, 表示, 先返回变量里面已有的值, get 在后返回变量操作完之后的新值
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41572697/article/details/89390037