多线程之ReentrantLock
ReentrantLock
lock
- lock调用ReentrantLock中lock调用sync.acquire
/** Synchronizer providing all implementation mechanics */private final Sync sync;public void lock() { sync.acquire(1);}
- sync.acquire(1)则调用AbstractQueuedSynchronizer(AQS)下的acquire方法
public final void acquire(int arg) { if (!tryAcquire(arg) && //如果没有上锁,则将线程放入等待队列中 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt();}
- 将线程放入等待队列中的两个方法acquireQueued与addWaiter
先看addWaiter
/** * Creates and enqueues node for current thread and given mode. * * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared * @return the new node * 为当前线程和给定模式创建和排队节点。 * 参数:模式– Node.EXCLUSIVE 用于独占,Node.SHARED 用于共享 * 返回:新节点 */private Node addWaiter(Node mode) { //创建一个新节点 Node node = new Node(mode);//直到加入队列为止 for (;;) { //将尾节点用一个节点存储下来 Node oldTail = tail; //将新节点加入链表尾部 if (oldTail != null) { node.setPrevRelaxed(oldTail); if (compareAndSetTail(oldTail, node)) { oldTail.next = node; return node; } } else { initializeSyncQueue(); } }}
/** * Acquires in exclusive uninterruptible mode for thread already in * queue. Used by condition wait methods as well as acquire. * * @param node the node * @param arg the acquire argument * @return {@code true} if interrupted while waiting * 以独占不间断模式获取已在队列中的线程。由条件等待方法和获取使用。 * 参数:节点——节点arg – 获取参数 * 回报:如果在等待时被打断,则为true */final boolean acquireQueued(final Node node, int arg) { boolean interrupted = false; try { for (;;) { //获取该节点的前驱节点 final Node p = node.predecessor(); //判断是否是头节点,并尝试获取锁,等第一个节点释放锁就能获取锁 if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC return interrupted; } if (shouldParkAfterFailedAcquire(p, node)) interrupted |= parkAndCheckInterrupt(); } } catch (Throwable t) { cancelAcquire(node); if (interrupted) selfInterrupt(); throw t; }}
- 然后调用ReentrantLock中的静态内部类NonfairSync中tryAcquire,继承于Sync
static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); }}
- 然后调用ReentrantLock中静态内部类Sync中的nonfairTryAcquire方法,该类继承于AbstractQueuedSynchronizer
/** * Performs non-fair tryLock. tryAcquire is implemented in * subclasses, but both need nonfair try for trylock method. * 执行不公平的 tryLock。 tryAcquire 在子类中实现,但两者都需要对 trylock 方法进行非公平尝试。 */@ReservedStackAccessfinal boolean nonfairTryAcquire(int acquires) { //获取当前线程 final Thread current = Thread.currentThread(); //获取当前线程的状态,看是否上锁 int c = getState(); //判断当前线程是否上锁 if (c == 0) { //将当前线程的状态从0-》1 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;}
lock流程过程图
ReentrantLock的lock调用流程如下:
- 调用ReentrantLock中的lock方法,而lock方法中语句sync.acquire()调用AbstractQueuedSynchronizer类中的acquire()方法
- acquire() 方法调用ReentrantLock中的静态内部类NonfairSync中的tryAcquire(arg)方法,类NonfairSync继承于Sync类
- tryAcquire方法中代用Sync类中的nonfairTryAcquire()方法,主要用于设置必要的参数
unlock
- 第一步调用unlock,调用Sync中的release方法
/** Synchronizer providing all implementation mechanics */private final Sync sync;/** * Attempts to release this lock. * * If the current thread is the holder of this lock then the hold * count is decremented. If the hold count is now zero then the lock * is released. If the current thread is not the holder of this * lock then {@link IllegalMonitorStateException} is thrown. * * @throws IllegalMonitorStateException if the current thread does not * hold this lock */
public void unlock() { //释放一个 sync.release(1);}
- 第二步: sync.release(1);调用AQS中的release方法
/** * Releases in exclusive mode. Implemented by unblocking one or * more threads if {@link #tryRelease} returns true. * This method can be used to implement method {@link Lock#unlock}. * * @param arg the release argument. This value is conveyed to * {@link #tryRelease} but is otherwise uninterpreted and * can represent anything you like. * @return the value returned from {@link #tryRelease} */public final boolean release(int arg) { //尝试将持有当前锁的对象给释放掉 if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) //如果没有将当前线程释放掉,则将查找本线程在链表中的下一个节点,将其唤醒去抢占锁 unparkSuccessor(h); return true; } return false;}
- 如果没有将当前线程释放掉,则将查找本线程在链表中的下一个节点,将其唤醒去抢占锁
/** * Wakes up node's successor, if one exists. * 唤醒节点的后继者(如果存在)。 * 参数:节点——节点 * @param node the node */private void unparkSuccessor(Node node) { /* * If status is negative (i.e., possibly needing signal) try * to clear in anticipation of signalling. It is OK if this * fails or if status is changed by waiting thread. */ int ws = node.waitStatus; if (ws < 0) node.compareAndSetWaitStatus(ws, 0); /* * Thread to unpark is held in successor, which is normally * just the next node. But if cancelled or apparently null, * traverse backwards from tail to find the actual * non-cancelled successor. */ Node s = node.next; if (s == null || s.waitStatus > 0) { s = null; for (Node p = tail; p != node && p != null; p = p.prev) if (p.waitStatus <= 0) s = p; } if (s != null) LockSupport.unpark(s.thread);}
- 第三步:调用ReentrantLock中的tryRelease尝试将其释放
@ReservedStackAccessprotected final boolean tryRelease(int releases) { //将当前线程状态减1 int c = getState() - releases; //判断是否是当前线程所占的锁 if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) { free = true; //设置对当前独占访问权限者为null setExclusiveOwnerThread(null); } setState(c); return free;}
/*** 设置当前拥有独占访问权限的线程。 null参数表示没有线程拥有访问权限。此方法不会强加任何同步或volatile字段访 * 问。* 参数:线程——所有者线程*/protected final void setExclusiveOwnerThread(Thread thread) { exclusiveOwnerThread = thread;}