原创

Java中乐观锁与悲观锁,即互斥同步锁与非互斥同步锁

乐观锁又叫非互斥同步锁,悲观锁又叫互斥同步锁。

悲观锁的劣势

  • 阻塞和唤醒带来的性能开销。
  • 永久阻塞问题。如果持有锁的线程发生无限循环或者死锁等活跃性的问题,那么等待获取锁执行的线程将无法执行。
  • 优先级反转问题。如果我们设置了优先级,当优先级高的线程需要等待优先级低的线程锁的时候,会让线程的优先级反转。

悲观锁概念

持悲观态度,认为每次执行这个同步资源的时候都会有线程争抢这个资源,如果不锁住就会发生错误。所以每次执行时都会锁住,让其他人等待执行完成释放锁后在拿到锁再执行。如synchronizedLock接口相关类

乐观锁概念

持乐观态度,认为每次执行这个同步资源的时候都没有线程争抢这个资源。所以执行时不会锁住资源,在更新时会对比我修改期间数据有没有被别人修改过,如果数据与开始一致,证明只有我们自己在操作,就正常修改数据;如果数据与开始不一致,证明有人修改过,那么就不会修改数据,执行放弃、报错、重试等相关策略。如CAS算法实现的相关操作,原子类、并发容器等。git中push操作也是乐观锁,push时如果有人版本号领先我们,则提交失败。

开销对比

  • 悲观锁的开销主要是线程阻塞唤醒带来的性能开销。
  • 乐观锁的开销主要是线程自旋所带来的cpu性能开销。

使用场景

悲观锁适用于并发写入多的情况,适用于持有锁时间比较长的情况,悲观锁可以避免线程自旋的性能开销。

  • IO操作
  • 代码量大,逻辑比较多,相对来说比较耗时
  • 并发大,线程竞争激烈。

乐观锁适用于并发写入少,大部分是读取数据的场景。

相关文章

Java中锁的分类及概念

正文到此结束
本文目录