jdk1.8 J.U.C并发源码阅读------ReentrantLock源码解析

一、继承关系

public class ReentrantLock implements Lock, java.io.Serializable
实现了Lock接口、Serializable接口。

是一个独占锁,包含公平和非公平两种实现。


总结:
(1)继承了AQS抽象类实现了一个子类Sync,实现了抽象方法tryRelease,一个内部方法nonfairTryAcquire非公平锁的获取方式
(2)两个子类NonfairSync和FairSync,主要区别在与:公平锁即使当前锁是空闲的,也要查看CLH队列中是否还有其他线程在等待获取锁,如果有则获取失败,严格遵守“先到先得”的顺序;非公平锁调用lock时,首先就通过CAS尝试直接获取锁,失败则调用tryAcquire方法,该方法调用nonfairTryAcquire:如果当前锁是空闲的直接获取锁,忽略FIFO的顺序。
(3)lock接口的抽象方法:lock,lockInterruptibly,tryLock,tryLock(long time, TimeUnit unit),unlock()都是通过sync对象进行操作。
该类内部保存一个AQS子类sync的对象,在创建ReentrantLock对象时,就在构造方法内部创建了一个sync对象,所有操作都是通过sync对象进行的。


二、成员变量

/** Synchronizer providing all implementation mechanics */
    private final Sync sync;//是AQS抽象类的一个子类
//state在AQS中定义,表示当前锁被获取的次数


三、内部类

(1)Sync:继承了AbstractQueuedSynchronizer,有两个子类,是独占锁

abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;
       
        abstract void lock();
		
		//非公平的获取锁的方式,体现在:如果当前锁是空闲的,则该线程直接获取锁,忽略FIFO规则。
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
			//c锁的个数
            int c = getState();
			//当前锁没有被其他线程占有
            if (c == 0) {
			//当前线程直接获取锁
			//CAS将0修改成acquires
                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");
				//更新state的值
                setState(nextc);
                return true;
            }
            return false;
        }
		//释放锁。过程:如果当前线程不是锁的拥有者,则抛出非法异常;否则,计算释放锁后state的个数,如果为0,则代表当前线程释放了所有的锁,就将当前拥有锁的线程设置为null,不为0则更新state的值。返回值代表该线程是否完全释放了该锁(state是否为0)
        protected final boolean tryRelease(int releases) {
		//计算释放了锁后的state值
            int c = getState() - releases;
			//如果拥有锁的线程不是当前线程,则抛出非法异常IllegalMonitorStateException
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
			//如果当前线程释放了所有的锁,则锁处于空闲状态,同时通过setExclusiveOwnerThread将当前占有锁的线程设置为null
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
			//更新state的值
            setState(c);
            return free;
        }
		//判断锁是否被当前线程独占
        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();
        }

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

        // Methods relayed from outer class

        final Thread getOwner() {
            return getState() == 0 ? null : getExclusiveOwnerThread();
        }

        final int getHoldCount() {
            return isHeldExclusively() ? getState() : 0;
        }

        final boolean isLocked() {
            return getState() != 0;
        }

        /**
         * Reconstitutes the instance from a stream (that is, deserializes it).
         */
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            s.defaultReadObject();
            setState(0); // reset to unlocked state
        }
    }

(2)NonfairSync:继承自Sync,非公平独占锁的实现方式

static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

       //首先尝试通过CAS快速获取锁,获取失败则回归正常模式,通过AQS中的acquire方法获取锁
        final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }
		//AQS中的acquire方法获取锁:首先尝试通过tryAcquire获取锁,成功则返回,失败则调用addWaiter将该线程封装成一个CLH队列的node节点加入到队列的尾部,然后调用acquireQueued方法,在队列中根据FIFO顺序获取锁。
        protected final boolean tryAcquire(int acquires) {
		//调用了父类sync的nonfairTryAcquire方法获取锁
            return nonfairTryAcquire(acquires);
        }
    }

(3)FairSync:继承自Sync,公平独占锁的实现方式

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

		//直接调用AQS父类的aquire方法
        final void lock() {
            acquire(1);
        }

        //和非公平锁的区别:即使当前锁是空闲的,也要查看CLH队列中是否还有其他线程在等待获取锁,如果有则获取失败,严格遵守“先到先得”的顺序
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
			//当前锁是空闲的
            if (c == 0) {
			//当队列中已经没有其他等待获取锁的节点,就CAS设置锁的状态state,并且设置锁的占有者为当前线程
                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");
				//更新state的值
                setState(nextc);
                return true;
            }
			//获取锁失败
            return false;
        }
    }
	//AQS中的方法,判断CLH队列中是否还有除自己外等待获取锁的节点(first节点当前拥有锁)
	public final boolean hasQueuedPredecessors() {
       
        Node t = tail; // Read fields in reverse initialization order
        Node h = head;
        Node s;
        return h != t &&
            ((s = h.next) == null || s.thread != Thread.currentThread());
    }


四、方法

1、构造方法

sync是父类SYNC类型的,指向的对象是子类NonfairSync或者FairSync类型的
	//默认创建的是非公平锁
	public ReentrantLock() {
        sync = new NonfairSync();
    }
	//指定创建锁的类型
	public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }


2、lock接口中的方法

(1)lock

public void lock() {
	//直接调用sync的lock,根据具体类型是公平锁还是非公平锁来决定调用的lock类型
        sync.lock();
    }


(2)lockInterruptibly:调用的AQS的acquireInterruptibly来获取锁,调用的tryAcquire抽象方法在子类中实现的,中断则抛出异常

public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }


(3)tryLock:尝试获取锁,只做一次尝试,失败则返回,是一个非阻塞的方法,不用添加到CLH队列中。调用的是SYNC类中的nonfairTryAcquire非公平式获取锁

public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }


(4)tryLock(long timeout, TimeUnit unit):调用的是AQS中的tryAcquireNanos,若超时则取消该节点(CLH队列中状态变成cancelled),中断则抛出异常。需要添加到CLH队列中遵循FIFO顺序获取锁

public boolean tryLock(long timeout, TimeUnit unit)
            throws InterruptedException {
        return sync.tryAcquireNanos(1, unit.toNanos(timeout));
    }

(5)unlock:释放锁,调用的AQS中的release方法,具体为:调用SYNC中的tryRelease(该线程是否完全释放了锁,是则释放成功,否则失败(可能该线程是重入的拥有该锁,此次释放没有完全释放掉))方法释放锁,释放成功且该节点的waitStatus不为0,则调用unparkSuccessor唤醒后继节点

public void unlock() {
        sync.release(1);
    }


(6)newCondition:创建一个CONDITION队列,是AQS中的ConditionObject类的对象

public Condition newCondition() {
        return sync.newCondition();
    }

3、其他方法

(1)getHoldCount:当前线程拥有该锁的个数

public int getHoldCount() {
	//getHoldCount是SYNC类中的一个方法
        return sync.getHoldCount();
    }
	final int getHoldCount() {
            return isHeldExclusively() ? getState() : 0;
    }


(2)isHeldByCurrentThread:当前线程是否独占的拥有锁

public boolean isHeldByCurrentThread() {
        return sync.isHeldExclusively();
    }


(3)isLocked:锁是否不是空闲的

public boolean isLocked() {
//isLocked:SYNC类中的方法
        return sync.isLocked();
    }

(4)isFair:锁是否是一个公平锁

public final boolean isFair() {
        return sync instanceof FairSync;
    }

(5)getOwner:返回当前锁的占有者线程

protected Thread getOwner() {
        return sync.getOwner();
    }

(6)hasQueuedThreads:CLH队列中是否还有节点

public final boolean hasQueuedThreads() {
        return sync.hasQueuedThreads();
    }


(7)hasQueuedThread:thread线程是否在CLH队列中

public final boolean hasQueuedThread(Thread thread) {
        return sync.isQueued(thread);
    }


(8)getQueueLength:CLH队列的长度

public final int getQueueLength() {
        return sync.getQueueLength();
    }


(9)getQueuedThreads:返回当前队列中所有线程的集合

protected Collection<Thread> getQueuedThreads() {
        return sync.getQueuedThreads();
    }


(10)hasWaiters:返回condition对象的CONDITION队列中是否还有处于CONDITION状态的节点(只有当前独占拥有锁的线程才能查看,否则会抛出IllegalMonitorStateException异常)

public boolean hasWaiters(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
        return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition);
    }


(11)getWaitQueueLength:返回Condition队列中处于CONDITION状态的node的个数。只有拥有锁的线程才能查看CONDITION队列的情况

public final int getWaitQueueLength(ConditionObject condition) {
//如果该condition不是本对象拥有的,则抛出异常
        if (!owns(condition))
            throw new IllegalArgumentException("Not owner");
        return condition.getWaitQueueLength();
    }


(12)getWaitingThreads:返回CONDITION队列中处于CONDITION状态的线程的个数。只有拥有锁的线程才能查看CONDITION队列的情况

protected Collection<Thread> getWaitingThreads(Condition condition) {
        if (condition == null)
            throw new NullPointerException();
			//如果condition不是AQS中的ConditionObject类或者子类的对象则抛出异常
        if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject))
            throw new IllegalArgumentException("not owner");
			//返回CONDITION队列中处于CONDITION状态的线程的个数
        return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition);
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值