您当前的位置: 首页 > 

顧棟

暂无认证

  • 0浏览

    0关注

    227博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【JUC系列】LOCK框架系列之六 核心锁类之ReentrantLock

顧棟 发布时间:2022-04-29 06:00:00 ,浏览量:0

ReentrantLock

文章目录
  • ReentrantLock
    • 主要成员
      • 构造函数
      • Sync类
        • 源码部分
      • NonfairSync 非公平锁
      • FairSync公平锁
    • 示例分析
可重入指任意线程在获取到锁之后可以再次获取到该锁而不会被该锁阻塞。

可重入锁指支持可以重入的锁,该锁可以支持一个线程对资源的重复加锁。

线程再次获取锁问题: 锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则可以再次获取成功。

锁的最终释放问题:线程重复n此获取了锁,随后在第n次释放该锁后,其他线程能够获取到该锁。锁的最终释放要求对于获取进行计数自增,计数表示当前锁被线程重复获取的次数,而锁被释放时,计数自减,当计数等于0时表示该锁成功释放。

主要成员

ReentrantLock实现了Lock接口,并在内部创建了一个内部类Sync继承了AQS类。在Sync上又延伸出公平锁和非公平锁。在绝对时间上,先对锁进行获取请求一定先获取到,则该锁是公平的,反之,锁是非公平锁。 在这里插入图片描述

构造函数

ReentrantLock的构造函数如下

    // 无参构造函数 默认是非公平锁
    public ReentrantLock() {
        sync = new NonfairSync();
    }

    // 有参构造函数 true是公平锁 false是非公平锁
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
Sync类

sync继承了AbstractQueuedSynchronizer。主要还是依托于AQS进行锁的管理。初识AQS

存在如下方法和作用如下:

方法名说明void lock();获取锁,由子类实现boolean nonfairTryAcquire(int acquires)非公平方式获取同步状态 true成功获取;false获取失败boolean tryRelease(int releases)释放状态,true成功释放;false释放失败boolean isHeldExclusively()判断资源是否被当前线程占有 true代表当前线程占用,false代表其他线程占用ConditionObject newCondition()创建一个新的condition对象Thread getOwner()或者当前占用线程,null代表为有占用者线程int getHoldCount()返回目前占用的状态(次数) 0代表未被占用boolean isLocked()资源是否被锁了(占用),true已被占用,false未被占用void readObject(java.io.ObjectInputStream s)自定义反序列化逻辑 源码部分
    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

        /**
         * Performs {@link Lock#lock}. The main reason for subclassing
         * is to allow fast path for nonfair version.
         * 获取锁的方法,由子类具体实现
         */
        abstract void lock();

        /**
         * Performs non-fair tryLock.  tryAcquire is implemented in
         * subclasses, but both need nonfair try for trylock method.
         * 非公平方式获取锁
         */
        final boolean nonfairTryAcquire(int acquires) {
            // 当前线程
            final Thread current = Thread.currentThread();
            // 获取状态
            int c = getState();
            // 0代表目前没有线程竞争该锁
            if (c == 0) {
                // 通过CAS操作占用锁,占用成功的话,直接结束该方法
                if (compareAndSetState(0, acquires)) {
                    // 将当前线程变成资源的占用者
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // 当前线程就是该锁的占用者
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc             
关注
打赏
1663402667
查看更多评论
0.0365s