前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ReentrantLock源码解析(1)

ReentrantLock源码解析(1)

作者头像
黑洞代码
发布2021-01-14 15:15:12
2390
发布2021-01-14 15:15:12
举报

ReentrantLock源码解析

概述


1.ReentrantLock用法

2.Sync源码

3.公平锁模式

4.非公平锁模式

第1节 ReentrantLock用法


ReentrantLock公平锁基本用法如下。

代码语言:javascript
复制
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();
            }
        }
    }
}

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

代码语言:javascript
复制
获得锁的线程:0
获得锁的线程:1
获得锁的线程:2
获得锁的线程:0
获得锁的线程:1
获得锁的线程:2
获得锁的线程:4
获得锁的线程:4
获得锁的线程:3
获得锁的线程:3


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

代码语言:javascript
复制
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();
            }
        }
    }
}

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

代码语言:javascript
复制
获得锁的线程:4
获得锁的线程:4
获得锁的线程:2
获得锁的线程:2
获得锁的线程:0
获得锁的线程:0
获得锁的线程:3
获得锁的线程:3
获得锁的线程:1
获得锁的线程:1

第2节 Sync源码


Lock接口API如下。

代码语言:javascript
复制
public interface Lock {

    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

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

    void unlock();

    Condition newCondition();
}

ReentrantLock类的声明如下。

代码语言:javascript
复制
public class ReentrantLock implements Lock, java.io.Serializable

ReentrantLock类有3个内部类,分别是Sync,FairSync和NonfairSync。FairSync和NonfairSync都继承自Sync。因此Sync是ReentrantLock的核心。Sync类的源码如下。

代码语言:javascript
复制
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公平锁的实现。

代码语言:javascript
复制
/**
 * 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非公平锁的实现。

代码语言:javascript
复制
/**
 * 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);
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档