ReentrantLock源码分析

上一篇文章重点分析了AQS的源码,有了这个认识,我们再看ReentrantLock的源码,会简单很多,来看下这个类

	// 创建一个锁
	ReentrantLock lock = new ReentrantLock();	
	
	// 默认是非公平锁,提升效率
	public ReentrantLock() {
        sync = new NonfairSync();
    }
    // 属性
    private final Sync sync;

看下Sync这个ReentrantLock的静态内部抽象类

	abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;
	        
        abstract void lock();
        // 非公平式尝试独占获取资源实现
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            // 0表示没有任何线程占用
            if (c == 0) {
            	// 设置成功,非公平,不管前面是否有其他线程抢占资源
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // 有线程占用,查看是否是当前线程,可能是重入锁
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
        
		// 独占式释放锁自定义实现
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            // 释放成功
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            // 如果是重入了多次的话,返回也是false
            return free;
        }
		// 判断是否是当前线程持有资源
        protected final boolean isHeldExclusively() {
            return getExclusiveOwnerThread() == Thread.currentThread();
        }
		...
    }

NonfairSync继承了Sync抽象类,来看代码

	static final class NonfairSync extends Sync {
       	// 非公平抢占资源,可以看到先尝试抢占一次资源(可耻的插队行为)
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            // 插队失败再调用独占式获取资源方法acquire
            else
                acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
        	// 调用nonfairTryAcquire方法,上面有分析过
            return nonfairTryAcquire(acquires);
        }
    }

FairSync继承了Sync抽象类来看代码,来看代码

	static final class FairSync extends Sync {
        //公平锁,老实排队获取
        final void lock() {
            acquire(1);
        }
		
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            // 当前资源可用
            if (c == 0) {
            	// 查看当前线程前置节点是否有线程排队
            	// 排好队,一个一个来
            	// 如果没有前置节点了,则尝试获取共享资源
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }

查看释放锁方法

	public void unlock() {
		// 一次释放一个资源
        sync.release(1);
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值