最清晰明了的ReentrantLock源码解析,你懂了吗?

概述

1.ReentrantLock用法
2.Sync源码
3.公平锁模式
4.非公平锁模式

第1节 ReentrantLock用法

ReentrantLock公平锁基本用法如下。

public class ReentrantLockTest {
    /**
     * 公平锁模式
     */
    private static Lock lock = new ReentrantLock(true);
    
    /**
     * 非公平锁模式
     */
//    private static Lock lock = new ReentrantLock(false);

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new ThreadDemo(i)).start();
        }
    }

    static class ThreadDemo implements Runnable {
        Integer id;

        public ThreadDemo(Integer id) {
            this.id = id;
        }

        @Override
        public void run() {
            try {
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < 2; i++) {
                lock.lock();
                System.out.println("获得锁的线程:" + id);
                lock.unlock();
            }
        }
    }
}

执行以上代码,执行结果如下。

获得锁的线程:0
获得锁的线程:1
获得锁的线程:2
获得锁的线程:0
获得锁的线程:1
获得锁的线程:2
获得锁的线程:4
获得锁的线程:4
获得锁的线程:3
获得锁的线程:3

ReentrantLock非公平锁基本用法如下。

public class ReentrantLockTest {
    /**
     * 公平锁模式
     */
//    private static Lock lock = new ReentrantLock(true);

    /**
     * 非公平锁模式
     */
    private static Lock lock = new ReentrantLock(false);

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new ThreadDemo(i)).start();
        }
    }

    static class ThreadDemo implements Runnable {
        Integer id;

        public ThreadDemo(Integer id) {
            this.id = id;
        }

        @Override
        public void run() {
            try {
                TimeUnit.MILLISECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for (int i = 0; i < 2; i++) {
                lock.lock();
                System.out.println("获得锁的线程:" + id);
                lock.unlock();
            }
        }
    }
}

执行以上代码,执行结果如下。

获得锁的线程:4
获得锁的线程:4
获得锁的线程:2
获得锁的线程:2
获得锁的线程:0
获得锁的线程:0
获得锁的线程:3
获得锁的线程:3
获得锁的线程:1
获得锁的线程:1

第2节 Sync源码

Lock接口API如下。

public interface Lock {

    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

    void unlock();

    Condition newCondition();
}

ReentrantLock类的声明如下。

public class ReentrantLock implements Lock, java.io.Serializable

在这里插入图片描述
ReentrantLock类有3个内部类,分别是Sync,FairSync和NonfairSync。FairSync和NonfairSync都继承自Sync。因此Sync是ReentrantLock的核心。Sync类的源码如下。

abstract static class Sync extends AbstractQueuedSynchronizer {
    private static final long serialVersionUID = -5179523762034025860L;

    /**
     * 加锁方法,由Sync的子类FairSync、NonfairSync实现。
     */
    abstract void lock();

    /**
     * 非公平方式加锁。
     */
    final boolean nonfairTryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        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;
    }

    /**
     * 对类AQS中的tryRelease()做重写。
     */
    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);
        return free;
    }

    /**
     * 对类AQS中的isHeldExclusively()做重写。
     */
    protected final boolean isHeldExclusively() {
        // While we must in general read state before owner,
        // we don't need to do so to check if current thread is owner
        return getExclusiveOwnerThread() == Thread.currentThread();
    }

    /**
     * 返回一个AQS内部类ConditionObject对象。
     */

    final ConditionObject newCondition() {
        return new ConditionObject();
    }

    /**
     * 返回锁的持有者。
     */
    final Thread getOwner() {
        return getState() == 0 ? null : getExclusiveOwnerThread();
    }

    /**
     * 返回重入锁重进入的次数。
     */
    final int getHoldCount() {
        return isHeldExclusively() ? getState() : 0;
    }

    /**
     * 判断是否已经被加锁。
     */
    final boolean isLocked() {
        return getState() != 0;
    }

    /**
     * 通过流反序列化对象。
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();
        setState(0); // reset to unlocked state
    }
}

第3节 FairSync公平源码解析

FairSync是ReentrantLock公平锁的实现。

/**
 * FairSync继承Sync,实现公平锁。
 */
static final class FairSync extends Sync {
    private static final long serialVersionUID = -3000897897090466540L;

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

    /**
     * 重写父类acquire()方法。
     */
    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;
    }
}

第4节 NonfairSync非公平源码解析

NonfairSync是ReentrantLock非公平锁的实现。

/**
 * FairSync继承Sync,实现非公平锁。
 */
static final class NonfairSync extends Sync {
    private static final long serialVersionUID = 7316153563782823691L;

    /**
     * 加锁。
     */
    final void lock() {
        if (compareAndSetState(0, 1))
            setExclusiveOwnerThread(Thread.currentThread());
        else
            acquire(1);
    }
    /**
     * 重写父类acquire()方法。
     */
    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}

最后

不知道这个知识点有没有帮助到大家,想了解更多的技术性文章,和领取免费架构资料

扫描下面二维码关注我们吧~

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值