如何理解Java中眼花缭乱的各种并发锁?

在互联网公司面试中,很多小伙伴都被问到过关于锁的问题。 今天,我给大家一次性把Java并发锁的全家桶彻底讲明白。包括互斥锁、读写锁、重入锁、公平锁、悲观锁、自旋锁、偏向锁等等等等。视频有点长,大家一定要全部看完,保证你会醍醐灌顶。

1、锁的由来

在并发编程中,经常会遇到两个以上的线程访问同一个共享变量,当同时对共享变量进行读写操作时,就会产生数据不一致的情况。

在这里插入图片描述

随着线程并发技术的发展,在多线程环境中,对线程访问资源的限制也越来越多。为了保证资源获取的有序性和占用性,都是通过并发锁来控制的。

2、锁的应用场景

下面,我根据个人经验以及并发场景下线程的处理逻辑,总结为以下7个场景,不同场景使用不同的锁。

1)某个线程是否锁住同步资源的情况

如果要锁住同步资源则使用悲观锁,不锁住同步资源使用乐观锁。 所谓悲观锁,就是每次拿数据的时候都认为会有别人修改,所以在读数据的时候都会上锁,其他线程数据就会阻塞,直到拿到锁。

在这里插入图片描述

举个例子,假设厕所只有一个坑位,悲观锁就是上厕所会第一时间把门反锁上,这样其他人上厕所只能在门外等候,这就是阻塞。

在这里插入图片描述

而乐观锁就是开着门,当然在这个场景下一般也不会这么做。所以,乐观锁,就是每次拿数据的时候都假设为别人不会修改,所以不会上锁;只是在更新数据的时候去判断之前有没有别的线程更新了这个数据。如果这个数据没有被更新,当前线程将自己修改的数据成功写入。如果数据已经被其他线程更新了,要么报错,要么自动重试。

在这里插入图片描述

乐观锁与悲观锁是一种广义上的概念,没有谁优谁劣。乐观锁适用于写少读多的场景,因为不用上锁、释放锁,省去了锁的开销,从而提升了吞吐量。 而悲观锁适用于写多读少的场景,因为线程间竞争激励,如果使用乐观锁会导致线程不断进行重试,这样反而还降低了性能。

2)多个线程是否共享一把锁的情况

如果在并发情况下,多个线程共享一把锁就是使用共享锁,如果不能共享一把锁就是排它锁或者叫独占锁、独享锁。 共享锁是指锁可被多个线程所持有。如果一个线程对数据加上共享锁后,那么其他线程只能对数据再加共享锁,不能加独占锁。获得共享锁的线程只能读数据,不能修改数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tom 弹架构

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值