ReentrantLock----独占式重入锁的深入理解

25 篇文章 0 订阅

ReentrantLock是重入锁

重入:表示能够对共享资源重复加锁,即当前线程再次获取锁时不会被阻塞。

1. 那重入锁是如何实现的呢?

如果该同步状态不为0,表示此时同步状态已被线程获取。再判断持有同步状态的线程是否是当前线程,如果是,同步状态再次+1并返回true,表示持有线程重入同步块。

释放过程:
当且仅当同步状态减为0并且持有线程为当前线程时表示锁被正确释放。
否则调用setState()将减1后的状态设置回去。

ReentrantLock提供了两种锁机制:公平锁、非公平锁

2. 公平锁与非公平锁

公平锁:锁的获取顺序符合时间上的顺序,即等待时间最长的线程最先获取锁。

    public ReentrantLock() {
        sync = new NonfairSync();
    }

我们提供源码可以发现ReentrantLock无参构造使用的是非公平锁。

要使用公平锁,就调用ReentrantLock有参构造传入ture,获取内置的公平锁

    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

公平锁的实现

    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        final void lock() {
            acquire(1);
        }

        /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         */
        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;
        }
    }

它里边最重要的就是这段代码:

//获取同步状态之前先判断下当前节点是否有前驱节点,如果有,获取失败
 if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }

直到它前边没有节点,才让这个节点获得锁,这就保证了等待时间最长的最先获取到锁(因为是尾插)。

那为什么ReentrantLock默认采用的是非公平锁,因为非公平锁的效率比公平锁高100倍以上,这是因为非公平锁省略了上下文切换等操作。

公平锁与非公平锁的对比:
公平锁保证了获取到锁的线程一定是等待时间最长的线程,保证了请求资源时间上的绝对顺序,需要频繁的进行上下文切换,性能开销较大。

非公平锁保证系统有更大的吞吐量(效率较高),但是会造成线程“饥饿现象”(有的线程可能永远无法获得锁)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值