Java悲观锁与乐观锁介绍,优缺点

什么是锁,为什么需要锁

        在Java中,锁是一种同步机制,用于控制多个线程对共享资源的访问。共享资源可以是变量、方法或对象。当多个线程同时尝试访问共享资源时,可能会发生竞争条件,导致不可预测的行为。

数据错误例子

假设有一个简单的股票交易系统,其中两个线程分别代表买家和卖家。买家线程和卖家线程同时尝试购买和卖出股票,但是没有使用锁来保护共享资源。

  1. 买家线程和卖家线程同时检查库存,结果都发现还有股票可供购买或出售。于是,两个线程同时减少库存,导致库存数量减少两次,从而导致数据错误。
  2. 买家线程和卖家线程同时尝试增加库存,但由于买方和卖方都在尝试增加同一个变量(stockCount)的值,可能导致该变量的值不正确。
  3. 买家线程和卖家线程同时增加买家和卖家的股票数量,可能导致两个线程增加的数量不正确,从而导致数据错误。

        为了确保对共享资源的访问不会发生冲突,需要使用锁来保证同一时刻只有一个线程能够访问共享资源

悲观锁和乐观锁都是一种锁优化策略,用于减少锁的使用和锁竞争,从而提高并发性能。

什么是悲观锁

        当多个线程同时尝试获取同一个锁时,悲观锁策略会假设最坏的情况,即假定多个线程同时获取锁会导致数据不一致。因此,它会采取一种较为保守的策略,避免多个线程同时获取锁。

对数据采取“悲观”态度,认为数据随时都有可能被别人改。

读取的时候就开始霸占,别人想改得排队,等我改完再说。

优点:

1. 有序队列

2. 无重试开销

3. 业务开发无需复杂的适配逻辑,符合线性开发思维

缺点:

  1. 产生饥饿:在某些情况下,悲观锁可能会导致饥饿现象,即某些线程长时间得不到锁,而其他线程却可以随时获得锁。这可能会导致某些线程长时间处于阻塞状态,从而影响程序的性能。
  2. 资源占用:悲观锁在等待锁的过程中会占用CPU资源,从而可能导致CPU资源占用过高。
  3. 死锁:在某些情况下,悲观锁可能会导致死锁现象,即多个线程相互等待对方释放锁,从而导致程序无法继续执行。

什么是乐观锁

        乐观锁的核心思想是在获取锁之前先进行尝试性读取共享资源,如果读取成功,则认为没有其他线程同时访问该资源,可以获取锁并进行写入操作。如果读取失败,则说明有其他线程同时访问该资源,需要重新进行读取并尝试获取锁。

对数据采取“乐观”态度,认为我在修改数据的同时,数据大概率不会被别人动过。

读数据不独占,而是保存修改的时候再检查一下是否变更(同时),如果被改过了,就重读重做。

优点:

1. 无堵塞风险

2. 业务不排队,高效率优先

3. 最大化整体效率

缺点:

  1. 代码复杂性:在使用乐观锁时,需要考虑重试策略、超时等问题,这可能会导致代码复杂性增加,维护成本提高。
  2. 如果发生了频繁的业务间修改冲突,就会引发频繁重复的重试,造成计算资源的浪费。
  3. 并发读操作:在乐观锁中,读取操作不需要加锁,因此可能会有多个线程同时进行读取操作,这可能会导致读取结果不一致。

悲观锁与乐观锁哪个更好

各业务之间处理时间相近:悲观锁

各业务之间处理时间差异大:乐观锁

并非绝对,根据具体情况调整

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值