ReentrantLock的源码分析:
ReentrantLock:
public class ReentrantLock implements Lock, java.io.Serializable
abstract static class Sync extends AbstractQueuedSynchronizer
static final class FairSync extends Sync {
final void lock() {
acquire(1);
}
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;
}
}
static final class NonfairSync extends Sync
AQS:
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable
private transient Thread exclusiveOwnerThread;
private transient volatile Node head;
private transient volatile Node tail;
private volatile int state;
static final class Node {
static final Node SHARED = new Node();
static final Node EXCLUSIVE = null;
static final int CANCELLED = 1;
static final int SIGNAL = -1;
static final int CONDITION = -2;
static final int PROPAGATE = -3;
volatile int waitStatus;
volatile Node prev;
volatile Node next;
volatile Thread thread;
Node nextWaiter;
// 排队
private Node enq(final Node node) {
for (;;) {
Node t = tail;
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
}
// 加锁
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
// 判断队列有没有初始化
public final boolean hasQueuedPredecessors() {
Node t = tail;
Node h = head;
Node s;
return h != t && // 如果 h == t 说明队列没有元素或有一个元素,h != t 说明队列至少有两个元素
((s = h.next) == null || s.thread != Thread.currentThread());
}
// 入队
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
enq(node);
return node;
}
// 自旋
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);
}
}
// 是否要进入自旋:只有队列的第一个队列需要进行自旋操作
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
// 如果上一个Node的waitStatus == -1.
if (ws == Node.SIGNAL)
return true;
if (ws > 0) {
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
// 如果上一个Node的waitStatus == 0,就设置为 -1(代表获取锁)
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
锁:解决多线程并发同步问题
1)自旋
2)CAS
3)park和unpark (USAFE)
4)在线程交替执行(没有竞争锁)和队列无关,在jdk级别解决同步问题。
公平锁示例:lock
1)第一个线程t1获取锁时,先查看 status == 0 && 队列有没有初始化-没有,对status进行cas操作(status = 1)获取锁,使当前线程为执行线程。
2)第二个线程t2获取锁时,先查看 status == 1 && 当前线程不是执行线程,执行入队操作:判断队列有没有初始化-没有,先创建一个 thread = null 的节点,再创建 thread = t2 的 Node 放在 null Node 后面,先尝试获取锁,如果获取不到就park,进入自旋。
3)第三个线程t3获取锁时,先查看 status == 1 && 当前线程不是执行线程,执行入队操作:判断队列有没有初始化-有,创建thread = t3 的 Node 放在 t2 后面。
t1 释放锁,status == 0 通知队列
4)第四个线程t4获取锁时,先查看 status == 0 && 队列有没有初始化-有,入队。
扩展:acquireQueued 的 interrupted 是给下面方法使用的
interrupt(),在一个线程中调用另一个线程的interrupt()方法,即会向那个线程发出信号——线程中断状态已1653被设置。至于那个线程何去何从,由具体的代码实现决定。
isInterrupted(),用来判断当前线程的中断状态(true or false)。
interrupted()是个Thread的static方法,用来恢复中断状态
try {
lock.lockInterruptibly();
} catch (InterruptedException e) {
//处理 InterruptedException
}