Lock 锁

Lock 锁:
为什么 synchronize 不够用
1) 效率低
2) 不够灵活
3) 无法知道是否获取到锁
lock() 方法不能被中断,死锁时会陷入无限等待
tryLock() 超时就放弃
lockInterruptibly() 相当于tryLock() 把超时时间设置为无限,
在等待锁的过程中,可以被中断

锁的可见性保证:
happens-before 原则
lock 的加解锁和 synchronize 有相同的语义,也就是说,
下一个线程加锁后可以看到前一个线程加锁前发生的所有操作

锁的分类:
从不同角度出发:
1. 线程要不要锁住同步资源:锁住–悲观锁(互斥同步锁),不锁住–乐观锁(非互斥同步锁)
2. 多个线程能否共享一把锁:可以–共享锁,不可以–独占锁
3. 多线程竞争时,是否排队:排队–公平锁,先尝试插队,插队失败在排队–非公平锁
4. 同一个线程是否可以重复获得一把锁:可以–可重入锁,不可以–不可重入锁
5. 是否可中断:可以–可中断锁,不可以–非可中断锁
6. 等锁的过程:自旋–自旋锁,阻塞–非自旋锁

悲观锁(互斥同步锁)
代表:synchronize 和 lock 相关的类
劣势:
1. 阻塞和唤醒带来的性能劣势
2. 可能陷入永久阻塞
3. 优先级反转
适用场景:
1. 适合并发写入多的情况,适用于临界区持有锁时间比较长的情况
悲观锁可以避免大量的无用自旋等情况
典型情况:
1. 临界区有 IO 操作
2. 临界区代码复杂或者循环量大
3. 临界区竞争非常激烈

乐观锁(非互斥同步锁)
一般采用 CAS 算法来实现
例子:Git 检查版本号,版本号一致则可以提交成功,不一致提交失败
适用场景:
1. 并发写入少,大部分是读取的场景,不加锁能让读取性能大幅提高

可重入锁:
以 ReentrantLock 为例
好处:避免死锁、提高封装性

公平锁和非公平锁
tryLock() 不遵守公平的规则

共享锁和排他锁
ReentrantReadWriteLock 不允许读锁插队,允许降级不允许升级
ReentrantReadWriteLock 公平锁的情况下不允许插队
非公平的情况下,写锁可以随时插(读锁的)队,读锁仅在等待队列头,不是想获取写锁线程的时候可以插队

锁的升降级:
锁支持降级(写锁->读锁),不支持升级
降级好处:可以提高效率

自旋锁和阻塞锁:
自旋例子:AtomicInteger
自旋锁适用场景:1. 一般适用于多核服务器,在并发度不是特别高的情况下,比阻塞锁的效率高
2. 自旋锁适用于临界区比较短小的情况下(共享资源占用时间短)

优化锁:
1. 缩小同步代码块
2. 尽量不要锁住方法
3. 减少请求锁的次数
4. 避免人为制造“热点”
5. 锁中不要再包含锁
6. 选择合适的锁类型或合适的工具类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C++中,unique_lock是一个用于管理互斥的RAII(资源获取即初始化)类。它提供了一种更灵活的方式来管理互斥的加和解操作。 unique_lock的解操作非常简单,只需要调用其成员函数unlock()即可。例如: ```cpp #include <iostream> #include <mutex> std::mutex mtx; void foo() { std::unique_lock<std::mutex> lock(mtx); // 互斥已经在构造unique_lock对象时被加 // 执行一些需要保护的操作 // 解互斥 lock.unlock(); // 在解后可以执行一些不需要互斥保护的操作 // 再次加互斥 lock.lock(); // 执行一些需要保护的操作 // 解互斥 lock.unlock(); } int main() { foo(); return 0; } ``` 在上面的示例中,我们首先创建了一个std::mutex对象mtx,然后在函数foo()中创建了一个unique_lock对象lock,并将mtx作为参数传递给它。在unique_lock对象的构造函数中,互斥会被自动加。然后我们可以执行一些需要保护的操作。当我们调用lock.unlock()时,互斥会被解,这样我们就可以执行一些不需要互斥保护的操作。最后,我们可以再次调用lock.lock()来重新加互斥,并执行一些需要保护的操作。最后,当unique_lock对象超出作用域时,析构函数会自动解互斥。 需要注意的是,unique_lock对象的unlock()和lock()成员函数可以在任何时候调用,而不仅仅是在构造函数和析构函数中。这使得我们可以更灵活地控制互斥的加和解操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值