在线精品99_中国九九盗摄偷拍偷看_91免费版在线观看_91.app_91高清视频在线_99热最新网站

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

145次阅读
没有评论

共计 2198 个字符,预计需要花费 6 分钟才能阅读完成。

这篇文章主要介绍 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 并发编程中悲观锁和乐观锁是什么意思”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注丸趣 TV 行业资讯频道!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计2198字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)
主站蜘蛛池模板: 国内精品视频一区 | 久久精品国产第一区二区 | 国产成人女人在线视频观看 | 人妻在卧室被老板疯狂进入 | 亚洲中文字幕无码一久久区 | 日韩一区二区三区在线免费观看 | 国产精品久久久久影视不卡 | 香蕉久久夜色精品国产 | 婷婷影院在线综合免费视频 | 亚洲色图偷拍视频 | 好吊妞视频这里有精品 | 韩国日本美国免费毛片 | 97香蕉网 | 美女视频黄是免费 | 日韩成人影院 | 王丽坤一级毛片免费观看 | 久久99九九精品免费 | 国产精品久久久久久久影院 | 国产伦理久久精品久久久久 | 久久精品国产精品青草色艺 | 亚洲精品无码一区二区三区久久久 | 欧洲美妇乱人伦视频网站 | 久久夜色精品国产亚洲av动态图 | 久久免费在线 | 国产成人免费观看在线视频 | 亚洲av无码国产一区二区三区 | 亚洲av乱码一区二区三区按摩 | 激情综合色五月丁香六月亚洲 | 人妻天天爽夜夜爽一区二区 | 人妻丰满熟妇av无码区hd | 开心五月激情综合婷婷色 | 一级毛片在线不卡直接观看 | 亚洲国产成人久久99精品 | 美女超爽久久久久网站 | 国内精品久久久久 | 毛片网站在线看 | 久久精品美女视频 | 精品福利在线播放 | 国产在线播放精品视频 | 少妇久久久久久被弄到高潮 | 999久久久无码国产精品 |