可重入锁、公平锁、非公平锁、互斥锁/独占锁/排他锁、共享锁源码分析

可重入锁:获取锁后再次请求获取同一把锁,不再抢占锁,而是只增加获得锁的次数。
synchronized、ReentrantLock是可重入锁。

公平锁:按照线程抢占锁的顺序使线程获得锁。

非公平锁:不按照线程抢占锁的顺序使线程获得锁。线程是否能抢占锁和线程抢占锁的顺序无关,随机抢占。

ReentrantLock默认是非公平锁。

    /**
     * Creates an instance of {@code ReentrantLock}.
     * This is equivalent to using {@code ReentrantLock(false)}.
     */
    public ReentrantLock() {
        sync = new NonfairSync();
    }

    /**
     * Creates an instance of {@code ReentrantLock} with the
     * given fairness policy.
     *
     * @param fair {@code true} if this lock should use a fair ordering policy
     */
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

互斥锁(也称独占锁、排他锁):多个线程不能获取同一把锁,如同步锁synchronized。

共享锁:多个线程可以获取同一把锁,如读写锁ReadWriteLock的读锁,读和读不互斥。读写锁的读和写互斥,写和写互斥。

AbstractQueuedSynchronizer.Node:

        /** Marker to indicate a node is waiting in shared mode */
        static final Node SHARED = new Node();
        /** Marker to indicate a node is waiting in exclusive mode */
        static final Node EXCLUSIVE = null;

跟踪一下lock()源码:

ReentrantLock:

    public void lock() {
        sync.acquire(1);
    }

 NonfairSync: 

        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

FairSync:

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

AQS:AbstractQueuedSynchronizer: 

    public final void acquire(int arg) {
        // tryAcquire(arg) 尝试获取锁是否成功
        // addWaiter(node)加入等待获取锁的队列
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }

NonfairSync: 

        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }

Sync:

        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState(); // private volatile int state;
            if (c == 0) {
                // 抢占锁,获取锁成功
                if (compareAndSetState(0, acquires)) { // unsafe.compareAndSwapInt(this, stateOffset, expect, update);
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                // 重入锁,线程获取次数+1,获取锁成功
                int nextc = c + acquires;
                if (nextc < 0) // 重入次数不能超过int最大值
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

FairSync: 

        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;
        }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风铃峰顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值