昨天看了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
ReentrantLock 实现原理详解 ReentrantLock 是 Java 中的一个同步工具类,它实现了 Lock 接口,提供了锁的获取和释放机制。ReentrantLock 的实现原理基于 AQS(AbstractQueuedSynchronizer),是一个重入锁,允许一...
这份资源旨在详细讲解 Java 中的 Locks 框架,特别关注 ReentrantLock 的使用和原理。Locks 框架提供了比传统的 synchronized 关键字更强大、更灵活的线程同步机制,而 ReentrantLock 是其中的一种重要实现。 Locks ...
一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个ReentrantLock流程看懂,干货满满 一张图将整个...
可重入锁: 也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,...ReentrantLock 在Java也是一个基础的锁,ReentrantLock 实现Lock接口提供一系列的基础函数,开发人员可以灵活的是应用函数满足各种复杂多变应用场景;
Lock、Synchronized 和 ReentrantLock 的使用 Lock、Synchronized 和 ReentrantLock 是 Java 中三种常用的同步机制,每种机制都有其特点和使用场景。下面对这三种机制进行详细的分析和比较。 一、Synchronized ...
1. ReentrantLock的介绍 ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁,支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。在java...
ReentrantLock源码剖析
什么是公平锁和非公平锁 公平与非公平的一个很本质的区别就是,是否遵守FIFO(也就是先来后到)。当有多个线程来申请锁的时候,是否先申请的线程先获取锁,后申请的线程后获取锁?如果是的,则是 公平锁 ,否则是...
ReentrantLock类可以唤醒指定条件的线程,而object的唤醒是随机的 Condition类和Object类 Condition类的awiat方法和Object类的wait方法等效 Condition类的signal方法和Object类的notify方法等效 Condition类...
使用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与...
简单聊聊Synchronized和ReentrantLock锁.docx
深入java并发编程,使用ReentrantLock和 Synchronized加锁