1、查看Lock类源码
lock的源码里只定义了5个方法,具体的实现逻辑我们去Lock的子类里进行查看
代码语言:javascript复制/*
* @since 1.5
* @author Doug Lea
*/
public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
void unlock();
Condition newCondition();
}
2、ReentrantLock类源码
先看ReentrantLock的父子关系,它继承了lock锁,相应的就要实现lock的方法,下面看他是怎么实现的
代码语言:javascript复制public class ReentrantLock implements Lock, java.io.Serializable
实现的lock方法,方法体内只有一行代码,调用了sync的lock方法,看一下这个sync是个什么
代码语言:javascript复制public void lock() {
sync.lock();
}
sync代码,ReentrantLock定义了一个Sync类,
代码语言:javascript复制 /** Synchronizer providing all implementation mechanics */
private final Sync sync;
/**
* Base of synchronization control for this lock. Subclassed
* into fair and nonfair versions below. Uses AQS state to
* represent the number of holds on the lock.
*/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
/**
* Performs {@link Lock#lock}. The main reason for subclassing
* is to allow fast path for nonfair version.
*/
abstract void lock();
/**
* Performs non-fair tryLock. tryAcquire is implemented in
* subclasses, but both need nonfair try for trylock method.
*/
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;
}
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;
}
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
}
}
在sync类里定义的lock方法是抽象方法没有具体实现的方法体,那lock的具体实现逻辑是在哪里执行的,看sync的子类:FairSync、NonfairSync
代码语言:javascript复制FairSync(公平锁):
代码语言:javascript复制 /**
* Sync object for fair locks
*/
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
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 (!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;
}
}
代码语言:javascript复制NonfairSync(非公平锁):
代码语言:javascript复制 /**
* Sync object for non-fair locks
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
代码语言:javascript复制那ReentrantLock是怎么定义用的是公平锁还是非公平锁的,使用构造函数定义,源码如下
代码语言:javascript复制 /**
* Creates an instance of {@code ReentrantLock}.
* This is equivalent to using {@code ReentrantLock(false)}.
*/
public ReentrantLock() {
sync = new NonfairSync();
}
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
当我们new ReentrantLock()的时候默认使用的非公平锁,如果想用公平锁就传递参数true,如下
代码语言:javascript复制new ReentrantLock(true)
上面都是ReentrantLock的基本实现,那它的锁是怎么控制的,我们来看非公平锁的lock内容
代码语言:javascript复制final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
先看验证条件:compareAndSetState(0, 1),调用的Sync的父类AbstractQueuedSynchronizer类的方法,调用了cas锁
代码语言:javascript复制 protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
如果验证通过执行AbstractQueuedSynchronizer的父类AbstractOwnableSynchronizer里的方法:setExclusiveOwnerThread(Thread.currentThread());
它的含义是保存获取当前锁的线程对象
代码语言:javascript复制 protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}
如果验证没通过,调用的Sync的父类acquire类的方法
代码语言:javascript复制 public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
这里干了三件事情:
- tryAcquire:会尝试再次通过CAS获取一次锁。
- addWaiter:将当前线程加入上面锁的双向链表(等待队列)中
- acquireQueued:通过自旋,判断当前队列节点是否可以获取锁。
addWaiter() 添加当前线程到等待链表中可以看到,通过CAS确保能够在线程安全的情况下,将当前线程加入到链表的尾部。
代码语言:javascript复制 /**
* Creates and enqueues node for current thread and given mode.
*
* @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared
* @return the new node
*/
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
acquireQueued() 自旋 CAS尝试获取锁
可以看到,当当前线程到头部的时候,尝试CAS更新锁状态,如果更新成功表示该等待线程获取成功。从头部移除。
代码语言:javascript复制 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;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
每一个线程都在 自旋 CAS
最后简要概括一下,获取锁的一个流程
unLock源码
代码语言:javascript复制 public void unlock() {
sync.release(1);
}
release源码
代码语言:javascript复制 public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
代码语言:javascript复制tryRelease源码,sync类重写了tryRelease
代码语言:javascript复制 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;
}
代码语言:javascript复制在最后的代码setState修改了AQS类里的state状态,释放锁就是对AQS中的状态值State进行修改。同时更新下一个链表中的线程等待节点。
总结
- lock的存储结构:一个int类型状态值(用于锁的状态变更),一个双向链表(用于存储等待中的线程)
- lock获取锁的过程:本质上是通过CAS来获取状态值修改,如果当场没获取到,会将该线程放在线程等待链表中。
- lock释放锁的过程:修改状态值,调整等待链表。