java悲观锁乐观锁

举报
object 发表于 2024/02/27 17:36:20 2024/02/27
【摘要】 悲观锁?悲观锁总是假设最坏的情况,认为总是会存在多个线程会同时修改数据,所以每次在获取资源操作的时都会进行上锁,在同一时间内,只允许一个线程使用,用完后释放资源。常见场景:synchronized,ReentrantLock代码示例:synchronized(this) { // 悲观锁synchronized操作}private Lock lock = new ReentrantLock...

悲观锁?

悲观锁总是假设最坏的情况,认为总是会存在多个线程会同时修改数据,所以每次在获取资源操作的时都会进行上锁,在同一时间内,只允许一个线程使用,用完后释放资源。

常见场景:synchronized,ReentrantLock

代码示例:

synchronized(this) {
  // 悲观锁synchronized操作
}

private Lock lock = new ReentrantLock();
lock.lock(); // 上锁
try {
  // 悲观锁lock操作
}finally{
  // 释放锁
}

乐观锁?

乐观锁总是假设最好的情况,认为总是不会存在多个线程同时修改数据,所以每次在获取资源操作时,不对资源进行上锁处理,允许多个资源同时操作,不过在进行操作前,需要确认数据未被篡改,若篡改,则拉取最新值。

常见常见:CAS,AutomicInteger

代码示例:

private AtomicInteger ami = new AtomicInteger();

public void increase() {
  ami.getAndIncrement();
}


 

private AtomicInteger ami = new AtomicInteger();

public void increase() {
  ami.getAndIncrement();
}


 两者的优劣:

悲观锁:使用于写场景较多的场景,可保证数据一致性。 但性能较低且可能存在线程死锁风险

乐观锁:使用于读操作较多的场景,不能完全保证数据一致性。但性能在读场景较多的场景下性能比悲观锁高,且不存在线程死锁风险。

    对于乐观锁,其主要的性能损耗在自旋阶段的频繁失败和重试,但空间足够的下,可通过空间换时间进行优化,例如LongAdder。

LongAdder:空间换时间。核心原理是通过将值计算均摊,常规CAS是判断是否被更新,更新则自旋,若存在大量线程的情况,则性能就比较低了。而LongAdder则是允许多个线程进行同时进行增量操作,最后将数据所有的增量进行计算,则保证了性能上的优化, 而允许多个线程同时操作,内部是通过一个数组进行统一管理,所以空间上增大了。缺点:也提到了,这里是基于增量操作,所以直接设置值的方法肯定不行,所以应用的场景有一定的限制

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。