欢迎光临散文网 会员登陆 & 注册

【Java并发】面试官问我CAS、乐观锁、悲观锁,我反手就是骑脸输出

2022-10-21 04:56 作者:裹魁钺  | 我要投稿


01:19




01:37


面试常问:

  1. 了解CAS吗?谈谈理解
  2. 用过AQS吗?举个例子
  3. 读过JUC源码吗?具体实现



01:58


P.S. 互斥锁:比如synchronized关键字、ReentrantLock

参考:https://blog.csdn.net/jiyiqinlovexx/article/details/51010176

悲观锁(Pessimistic Concurrency Control)

悲观:OS认为,若不严格同步(sync)线程调用,则一定会产生异常。

故:互斥锁将一个资源锁定,仅供一个线程调用,阻塞其他线程。




02:25





02:30





02:55


compare and swap


04:02


oldValue:代表之前读到的资源对象的状态值

newValue:代表享要将资源对象的状态值更新后的值

“此时AB线程争抢着去修改资源对象的状态值,然后占用它”

设a抢到了时间片,

a 对比 对象状态值=0, oldValue=0

二者compare,结果相等,符合预期,则swap对象状态值为1

b 对比 对象状态值=1, oldValue=0。

二者compare,结果不等,抢占失败,放弃swap操作。


04:46


实际应用,通常会让b进行自旋(不断第重试cas操作,且配置次数避免死循环)




05:16





05:29


没有同步操作,还是线程不安全

(若同时抢到,则同时swap为1,同步失败)

故,要是CAS线程安全,则:

campare和swap必须“被绑定”

  • campare & swap这个操作,必须满足同一时刻只能允许1个线程在进行

CAS必须是原子性的



06:03


各种架构的CPU提供了指令级别的CAS原子操作:

  • x86: cmpxchg
  • arm: LL/SC

即无需通过OS的同步原语(mutex),CPU硬件原生支持CAS,上层进行调用即可

但这不代表“无锁”能代替“有锁”。


06:44




06:57


乐观锁(Optimistic Concurrency Control):

  • 不会锁定资源
  • 当线程想要修改共享资源的对象时,总是会乐观地认为,对象状态值没有被其他线程修改过,而是每次都会自己主动尝试去compare状态值

乐观“锁”取名不恰当:因为其并没有用到锁,实为无锁的同步机制




07:30


示例需求:使用3个线程,将一个值,从0累加到1000

错误1 不使用任何同步机制

改进1 使用互斥锁同步线程

改进2 使用无锁编程同步线程

Atomic类是无锁编程的轮子

AtomicInteger 底层通过CAS来实现同步的计数器



09:25


Unsafe类型的示例

一个long类型的offset



09:55


直接调用unsafe对象的 incrementAndGet方法



10:12



自旋循环次数,可配置,默认为10


10:30


native boolean compareAndSwapInt

是一个本地方法


11:02








【Java并发】面试官问我CAS、乐观锁、悲观锁,我反手就是骑脸输出的评论 (共 条)

分享到微博请遵守国家法律