本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
ReentrantLock
与 synchronized 的主要区别
- 等待可中断。当持有锁的线程长时间不释放锁的时候,等待中的线程可放弃等待转而处理其它任务。
- 公平锁(可选)。可通过构造传参设置,使用公平锁会使性能急剧下降。
- 多条件。可同时绑定多个Condition条件对象。
实现 (AQS)
AQS (Abstract Queued Synchronizer - 抽象队列同步器)。
AQS内部维护一个state状态位,当尝试加锁时通过CAS修改值,若成功则将state置为1,并将当前线程ID赋值(代表加锁成功),一旦获取到锁,其他队列将被阻塞进入阻塞队列自旋。获得锁的线程释放锁时会唤醒阻塞队列中的线程,并将state重置为0,将当前线程ID置空。
CAS
CAS - Compare And Swap,比较并交换。主要通过处理器的指令来保证操作的原子性,它包含三个操作数:
- V:变量内存地址
- A:旧的预期值
- B:准备更新的新值
当执行CAS指令时,从地址V读取值A,执行多步计算来获得新值B,然后在更新V的值前重新读取预期原值A’,只有当V的值未被更改(A == A‘),处理器才更新V的值,否则处理器将不做操作。
缺陷
- ABA问题:在CAS更新过程中,当读取到的值和准备赋值时V处的值都为A时,在此期间V处的值可能先被改成了B再改回A。ABA问题在大部分场景下不影响并发的最终结果。若欲解决可向变量中加入标志字段,在更新比较时同时比较标志即可。
- 循环时间长开销大:自选CAS的方式如果长时间不成功会给CPU带来很大的开销。
- 只能保证一个共享变量的原子操作:如果想堆多个变量进行处理可以将其封装进同一变量、使用
AtomicReference处理或锁synchronized实现。