千家信息网

java并发编程中悲观锁和乐观锁是什么意思

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章主要介绍java并发编程中悲观锁和乐观锁是什么意思,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!悲观锁悲观锁是平时开发中经常用到的一种锁,比如ReentrantLock
千家信息网最后更新 2026年11月03日java并发编程中悲观锁和乐观锁是什么意思

这篇文章主要介绍java并发编程中悲观锁和乐观锁是什么意思,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

悲观锁

悲观锁是平时开发中经常用到的一种锁,比如ReentrantLock和synchronized等就是这种思想的体现,它总是假设别的线程在拿线程的时候都会修改数据,所以每次拿到数据的时候都会上锁,这样别的线程想拿这个数据就会被阻塞。如图所示:

synchronized是悲观锁的一种实现,一般我们都会有这样使用:

private static Object monitor = new Object();

public static void main(String[] args) throws Exception {
//锁一段代码块
synchronized (monitor){

}
}
//锁实例方法,锁对象是this,即该类实例本身
public synchronized void doSome(){

}
//锁静态方法,锁对象是该类,即XXX.class
public synchronized static void add(){

}

我们以最简单的同步代码块来分析,其实就是将synchronized作用于一个给定的实例对象monitor,即当前实例对象就是锁对象,每次当线程进入synchronized包裹的代码块时就会要求当前线程持有monitor实例对象锁,如果当前有其他线程正持有该对象锁,那么新到的线程就必须等待,这样也就保证了每次只有一个线程执行synchronized内包裹的代码块。

从上面的分析中可以看出,悲观锁是独占和排他的,只要操作资源都会对资源进行加锁。假设读多写少的情况下,使用悲观锁的效果就不是很好。这时就引出了接下来要讲的乐观锁。

乐观锁

乐观锁,顾名思义它总是假设最好的情况,线程每次去拿数据时都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新,则根据不同的实现方式执行不同的操作(例如报错或者自动重试)。如图所示:

一般乐观锁在java中是通过无锁编程实现的,最常见的就是CAS算法,比如Java并发包中的原子类的递增操作就是通过CAS算法实现的。

CAS算法,其实就是Compare And Swap(比较与交换)的意思。目的就是将内存的值更新为需要的值,但是有个条件,内存值必须与期待的原内存值相同。展开来说,我们有三个变量,内存值M,期望的内存值E,更新值U,只有当M==E时,才会将M更新为U。

CAS算法实现的乐观锁在很多地方有应用,比如并发包的原子类AtomicInteger类。在自增的时候就使用到CAS算法。

public final int getAndIncrement() {
return unsafe.getAndAddInt(this, valueOffset, 1);
}

//var1 是this指针
//var2 是偏移量
//var4 是自增量
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
//获取内存,称之为期待的内存值E
var5 = this.getIntVolatile(var1, var2);
//var5 + var4的结果是更新值U
//这里使用JNI方法,每个线程将自己内存中的内存值M与var5期望值比较,
//如果相同则更新为var5 + var4,返回true跳出循环。
//如果不相同,则把内存值M更新为最新的内存值,然后自旋,直到更新成功为止
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
//返回更新后的值
return var5;
}

public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);

所以可以看出CAS算法其实是无锁的。好处是在读多写少的情况下,性能是比较好的。那么CAS算法的缺点其实也是很明显的。

  • ABA问题。线程C将内存值A改成了B后,又改成了A,而线程D会认为内存值A没有改变过,这个问题就称为ABA问题。解决办法很简单,在变量前面加上版本号,每次变量更新的时候变量的 版本号都+1,即 A->B->A就变成了 1A->2B->3A。
  • 在写多读少的情况下,也就是频繁更新数据,那么会导致其他线程经常更新失败,那么就会进入自旋,自旋时会 占用CPU资源。如果资源竞争激烈,多线程自旋的时间长,导致 消耗资源。

使用场景

在读多写少的场景下,更新时很少发生冲突,使用乐观锁,减少了上锁和释放锁的开销,可以有效地提升系统的性能。

相反,在写多读少的场景下,如果使用乐观锁会导致更新时经常产生冲突,然后线程会循环重试,这样会增大CPU的消耗。在这种情况下,建议可以使用悲观锁。


以上是"java并发编程中悲观锁和乐观锁是什么意思"这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注行业资讯频道!

线程 更新 内存 乐观 数据 悲观 对象 就是 算法 实例 情况 时候 资源 代码 变量 意思 编程 相同 场景 方法 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 咖啡豆 有格互联网科技 国智互联网科技 互联网科技公司怎么样 深圳齐家互联网科技 唐信互联网科技 大连 卓越科技互联网 招聘 盛创互联网科技有限公司 广西拼得多互联网科技有限公司 互联网科技公司需要的职位 创业天下互联网科技有限公司 金融科技与互联网金融相同和不同 湖南诚度互联网科技有限公司 上海互联网科技公司ppt 互联网科技包装股份有限公司上市 长沙易易互联网科技有限公司 重庆科技产业互联网有哪些 瑞安市蟠桃会互联网科技有限公司 互联网大会出现的黑科技 利用互联网等科技手段 广东万易互联网科技有限公司惠州分公司 互联网科技公司起名 互联网核心科技是什么 互联网科技集团 顺玮阁互联网科技 掌上梦互联网科技 成都玖崟互联网科技有限公司乐商圈怎么样 无锡工业互联网科技有限公司 上海互联网科技公司ppt 互联网科技的前景
0