昨天看了reentrantLock的源码码,分析一下:
public class ReentrantLock implements Lock, java.io.Serializable { //调用AbstractQueuedSynchronizer的release方法 public void unlock() { sync.release(1); } //调用FairSync或者NonfairSync的lock方法 public void lock() { sync.lock(); } } //sync抽象类 static abstract class Sync extends AbstractQueuedSynchronizer { //如果当前锁未被占有,那么当前线程占有锁。如果锁被当前线程占有,更新状态 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; } //如果状态是0,并且当前线程是持有锁的线程//setExclusiveOwnerThread(null); 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; } } //非公平的sync final static class NonfairSync extends Sync { //锁住当前对象 final void lock() { //如果没有被锁,即state = 0,set state = 1 if (compareAndSetState(0, 1)) //让当前线程占有锁 setExclusiveOwnerThread(Thread.currentThread()); else //调用父类AbstractQueuedSynchronizer的acquire()方法 acquire(1); } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } } //公平的sync final static class FairSync extends Sync { private static final long serialVersionUID = - 3000897897090466540L; //调用AbstractQueuedSynchronizer中的acquire方法 final void lock() { acquire(1); } /** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { //判断前面是不是已经有线程在申请锁,公平锁需要等待 if (isFirst(current) && 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; } } public abstract class AbstractQueuedSynchronizer{ private static final long stateOffset; static { try { //state成员变量的偏移量 stateOffset = unsafe.objectFieldOffset (AbstractQueuedSynchronizer.class.getDeclaredField("state")); headOffset = unsafe.objectFieldOffset (AbstractQueuedSynchronizer.class.getDeclaredField("head")); tailOffset = unsafe.objectFieldOffset (AbstractQueuedSynchronizer.class.getDeclaredField("tail")); waitStatusOffset = unsafe.objectFieldOffset (Node.class.getDeclaredField("waitStatus")); nextOffset = unsafe.objectFieldOffset (Node.class.getDeclaredField("next")); } catch (Exception ex) { throw new Error(ex); } } //如果变量state的值等于expect,把state设置成update protected final boolean compareAndSetState(int expect, int update) { // See below for intrinsics setup to support this return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } //设置占有锁的线程 protected final void setExclusiveOwnerThread(Thread t) { exclusiveOwnerThread = t; } public final void acquire(int arg) { //调用子类的tryAcquire()方法,如果不能加锁acquireQueued返回true,那样//interrupt当前线程 if (!tryAcquire(arg) && //将当前线程加入等待队列中 acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); } public final boolean release(int arg) { //判定是否可以释放当前的锁 if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; } 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) compareAndSetWaitStatus(node, 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. * 先查看当前节点的下一个节点是不是有效的,如果有效就直接处理。如果无效就从tail开始往前找。默认情况下是会将先等待的节点,先唤醒 */ Node s = node.next; if (s == null || s.waitStatus > 0) { s = null; for (Node t = tail; t != null && t != node; t = t.prev) if (t.waitStatus <= 0) s = t; } if (s != null) //调用unsafe.unpark方法,unloke当前线程 LockSupport.unpark(s.thread); } } static final class Node { /** waitStatus value to indicate thread has cancelled */ static final int CANCELLED = 1; /** waitStatus value to indicate successor's thread needs unparking */ static final int SIGNAL = -1; /** waitStatus value to indicate thread is waiting on condition */ static final int CONDITION = -2; /** * waitStatus value to indicate the next acquireShared should * unconditionally propagate */ static final int PROPAGATE = -3; /** 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; /** * Status field, taking on only the values: * SIGNAL: The successor of this node is (or will soon be) * blocked (via park), so the current node must * unpark its successor when it releases or * cancels. To avoid races, acquire methods must * first indicate they need a signal, * then retry the atomic acquire, and then, * on failure, block. * CANCELLED: This node is cancelled due to timeout or interrupt. * Nodes never leave this state. In particular, * a thread with cancelled node never again blocks. * CONDITION: This node is currently on a condition queue. * It will not be used as a sync queue node * until transferred, at which time the status * will be set to 0. (Use of this value here has * nothing to do with the other uses of the * field, but simplifies mechanics.) * PROPAGATE: A releaseShared should be propagated to other * nodes. This is set (for head node only) in * doReleaseShared to ensure propagation * continues, even if other operations have * since intervened. * 0: None of the above * * The values are arranged numerically to simplify use. * Non-negative values mean that a node doesn't need to * signal. So, most code doesn't need to check for particular * values, just for sign. * * The field is initialized to 0 for normal sync nodes, and * CONDITION for condition nodes. It is modified only using * CAS. */ volatile int waitStatus; final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); //如果是第一个节点,则尝试去获取锁 if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return interrupted; } //获取失败,则会被pack if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } } //获取锁,但是当线程被中断的时候,抛出一个InterruptedException,和acquire方法的区别是acquire方法即使被中断也会继续尝试获取锁 public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg); } /** * Acquires in exclusive interruptible mode. * @param arg the acquire argument */ private void doAcquireInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.EXCLUSIVE); boolean failed = true; try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC failed = false; return; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } } }
其他参考http://www.iteye.com/topic/623398
思考:unsafe.compareAndSwapInt(this, stateOffset, expect, update);这个方法是线程安全的,有硬件方面的支持
相关推荐
ReentrantLock java除了使用关键字synchronized外,还可以使用ReentrantLock实现独占锁的功能。而且ReentrantLock相比synchronized而言功能更加丰富,使用起来更为灵活,也更适合复杂的并发场景。这篇文章主要是从...
java语言 并发编程 ReentrantLock与synchronized区别 详解
ReentrantLock的使用及注意事项
1、ReentrantLock简介 2、ReentrantLock函数列表 3、重入的实现 4、公平锁与非公平锁 5、ReentrantLock 扩展的功能 6
这份资源旨在详细讲解 Java 中的 Locks 框架,特别关注 ReentrantLock 的使用和原理。Locks 框架提供了比传统的 synchronized 关键字更强大、更灵活的线程同步机制,而 ReentrantLock 是其中的一种重要实现。 Locks ...
一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个...
可重入锁: 也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,...ReentrantLock 在Java也是一个基础的锁,ReentrantLock 实现Lock接口提供一系列的基础函数,开发人员可以灵活的是应用函数满足各种复杂多变应用场景;
1. ReentrantLock的介绍 ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。在java...
ReentrantLock源码剖析
什么是公平锁和非公平锁 公平与非公平的一个很本质的区别就是,是否遵守FIFO(也就是先来后到)。当有多个线程来申请锁的时候,是否先申请的线程先获取锁,后申请的线程后获取锁?如果是的,则是 公平锁 ,否则是...
ReentrantLock类可以唤醒指定条件的线程,而object的唤醒是随机的 Condition类和Object类 Condition类的awiat方法和Object类的wait方法等效 Condition类的signal方法和Object类的notify方法等效 Condition类...
ReentrantLock 实现原理 1
使用ReentrantLock和Lambda表达式让同步更纯净Java开发Java经验技巧共5页.pdf.zip
ReentrantLock lock方法注释
Java多线程ReentrantLock1
AQS和ReentrantLock.pdf
ReentrantLock的基本用法 2.1 创建ReentrantLock 2.2 获取锁和释放锁 公平性与非公平性 3.1 公平锁 3.2 非公平锁 中断响应 条件变量与Condition 5.1 创建Condition 5.2 await()和signal() 可重入性 ReentrantLock与...
Lock、Synchoronized和ReentrantLock的使用
深入java并发编程,使用ReentrantLock和 Synchronized加锁
ReentrantLock 是JDK给我们提供的显示锁 在功能上远远强于synchronized 是功能上 不是性能上,随着JDK版本的一代又一代升级 synchronized的性能已经远远不是以前的重量级锁那么沉重 ReentrantLock源码 我们来看...