Java并发编程7——AbstractQueuedSynchronizer / ReentrantLock(未完)

  • ReentrantLock
    • 介绍(与synchronized的区别)
    • 使用方式
    • 源码
      • NonfairSync 和 FairSync
  • AbstractQueuedSynchronizer(AQS)
    • 源码

8.1 ReentrantLock

(1)介绍(与synchronized的区别):除了synchronized之外的另一种独占锁

  • 从底层出发
    • synchronized基于jvm级别,因为加重量级锁时它会涉及到C++的Monitor对象
    • 而ReentrantLock属于API级别
  • 从性能出发
    • synchronized优化(引入偏向锁,自旋)之后,两者性能差不多,官方甚至建议使用synchronized
    • ReentrantLock粒度更小
  • 从设计者出发
    • synchronized更多的是悲观锁思想,自旋优化引入了点CAS乐观锁思想
    • ReentrantLock主要是乐观锁思想: 自旋 + park() + CAS
  • 从API层面出发:ReentrantLock的设计灵活性更强,有五大特点
    • 1. 独占锁:synchronized也是
    • 2. 可重入锁:synchronized也是
    • 3. 公平/非公平锁:ReentrantLock默认非公平;synchronized只支持非公平
    • 4. 响应中断:阻塞时可以被打断,synchronized不行
    • 5. 支持绑定多个Condition:synchronized不行

(2)使用方式API

(3)源码

AQS相关
  • abstract static class Sync extends AbstractQueuedSynchronizer
  • 内部类Sync继承了AQS
  • static final class NonfairSync extends Sync
  • static final class FairSync extends Sync
  • NonfairSync非公平锁:重写了lock()方法,加锁前先CAS试探一下,不公平之处体现在这
  • FairSync公平锁:重写了较多方法
  • private final Sync sync;
  • 内部属性,NonfairSync 或 FairSync
构造器
  • public ReentrantLock()
  • 默认非公平 sync = new NonfairSync();
  • public ReentrantLock(boolean fair)
  • 输入true创建公平锁
加锁解锁
  • void lock();
  • 内部代码调用sync方法:sync.lock();
  • 解释:获取锁,获取不到lock就不罢休,不可被打断,即使当前线程被中断,线程也一直阻塞,直到拿到锁
  • void lockInterruptibly() throws InterruptedException;
  • 内部代码调用sync方法:sync.acquireInterruptibly(1);
  • 解释:获取锁,可中断,如果获取锁之前当前线程被interrupt了,获取锁之后会抛出InterruptedException,并且停止当前线程
  • boolean tryLock();
  • boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
  • 内部调用:return sync.nonfairTryAcquire(1);
    • 解释:立即返回结果:尝试获得锁,如果获得锁立即返回ture,失败立即返回false
  • 内部调用:return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    • 解释:最多等待time时间:尝试拿锁,超时返回false,即过时不候
  • void unlock();
  • 内部调用:sync.release(1);
  • 解释:解锁
  • Condition newCondition();
  • 内部调用:return sync.newCondition();
  • 解释:返回当前线程的Condition ,可多次调用
其他方法
  • 看代码,略

(4)NonfairSync 和 FairSync

  • 具体讲一下NonfairSync的lock()方法:
    • 如果是非公平锁,新来加锁的线程它会先进行一次CAS(并不会公平排队,进入队列),万一另一线程正好释放了锁,该线程就拿到了锁。不公平体现在这里
  • static final class NonfairSync extends Sync {
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }
    }

8.2 AbstractQueuedSynchronizer(AQS)

猜你喜欢

转载自blog.csdn.net/qq_41157876/article/details/115324421
今日推荐