我相信JUC下的CountDownLatch,CyclicBarrier,Semaphore这三个组件很多人都使用过,这里就不浪费篇幅去使用了,下面来看一下他们是如何实现的。
首先这里需要有准备阶段,在看源码之前你需要了解AbstractQueuedSynchronizer和Condition类,这里可以查看我之前写的一篇博客AbstractQueuedSynchronizer源码解读
源码解析
CountDownLatch
它允许一个线程或多个线程去等待其他线程执行完成之后再去执行
构造方法
public CountDownLatch(int count) {//count表示有几个线程
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);//Sync是实现了AQS的内部类,count是赋值给了AQS的state
}
countDown方法
public void countDown() {
sync.releaseShared(1);//实际上是调用AQS的方法
}
releaseShared(int) 方法
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {//(tryReleaseShared(arg)实际上是减1,然后判断是不是为0
doReleaseShared();//为0就唤醒所有等待的线程,不为0直接返回
return true;
}
return false;
}
tryReleaseShared(int)方法
protected boolean tryReleaseShared(int releases) {
for (;;) {//自选,因为这里的逻辑使用了cas乐观锁
int c = getState();//获取state
if (c == 0)//是否为0
return false;
int nextc = c-1;//减1操作
if (compareAndSetState(c, nextc))//cas进行赋值
return nextc == 0;//是否为0,为0返回true,否则为false
}
}
doReleaseShared()方法
/**
*这里是循环调用每个线程LockSupport.unPork()方法去唤醒等待的线程
**/
private void doReleaseShared() {
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue;
unparkSuccessor(h);//这里实际上就是调用LockSupport.unPork()方法
}
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue; // loop on failed CAS
}
if (h == head) // loop if head changed
break;
}
}
等待方法await();
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);//实际上是调用了AQS的方法
}
acquireSharedInterruptibly(1)方法
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)//tryAcquireShared(arg)方法是判断state是否为0
doAcquireSharedInterruptibly(arg);//实际的入AQS同步队列的方法
}
doAcquireSharedInterruptibly(int)方法
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);//真正入队的方法,返回当前节点
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();//取当前节点的前一个节点
if (p == head) {
int r = tryAcquireShared(arg);//再判断一下state是否为0,直接执行当前线程
if (r >= 0) {//r>=0说明状态已经为0了,线程可以继续执行
setHeadAndPropagate(node, r);
p.next = null; // 删除当前节点
failed = false;
return;//直接返回执行
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())//shouldParkAfterFailedAcquire(p, node)是一系列判断逻辑,parkAndCheckInterrupt()将当前线程挂起的方法
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
parkAndCheckInterrupt()
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);//挂起当前线程
return Thread.interrupted();
}
CyclicBarrier
构造方法
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;//存储当前值,以便下次循环使用
this.count = parties;//计数
this.barrierCommand = barrierAction;//所有的线程执行完成,然后执行的线程,主要是有最后一个执行完的线程执行,后续会看到
}
await()方法
public int await() throws InterruptedException, BrokenBarrierException {
try {
return dowait(false, 0L);//具体的执行逻辑
} catch (TimeoutException toe) {
throw new Error(toe); // cannot happen
}
}
dowait(boolean , long )方法
private int dowait(boolean timed, long nanos)
throws InterruptedException, BrokenBarrierException,
TimeoutException {
final ReentrantLock lock = this.lock;
lock.lock();//加锁,多线程顺序访问
try {
final Generation g = generation;
if (g.broken)
throw new BrokenBarrierException();
if (Thread.interrupted()) {//如果当前线程被中断,就唤醒所有的线程
breakBarrier();//实际上是调用了condition.signalAll()方法,唤醒所有等待的线程
throw new InterruptedException();
}
int index = --count;//减1
if (index == 0) { //如果为0,说明所有线程都已经执行完成了
boolean ranAction = false;
try {
final Runnable command = barrierCommand;
if (command != null)
command.run();//调用构造方法里的那个线程的run,这里可以发现是有最后一个线程调用的
ranAction = true;
nextGeneration();//唤醒所有线程,并且重新创建一个Generation类,这里可以看出,CyclicBarrier可以重复使用
return 0;
} finally {
if (!ranAction)
breakBarrier();
}
}
for (;;) {
try {
if (!timed)
trip.await();//当前线程等待
else if (nanos > 0L)
nanos = trip.awaitNanos(nanos);
} catch (InterruptedException ie) {
if (g == generation && ! g.broken) {
breakBarrier();
throw ie;
} else {
Thread.currentThread().interrupt();
}
}
if (g.broken)
throw new BrokenBarrierException();
if (g != generation)
return index;
if (timed && nanos <= 0L) {
breakBarrier();
throw new TimeoutException();
}
}
} finally {
lock.unlock();
}
}
nextGeneration()方法
private void nextGeneration() {
// signal completion of last generation
trip.signalAll();//condition.signalAll()唤醒所有等待的线程
// set up next generation
count = parties;//重新赋值,复用
generation = new Generation();//重新创建一个对象,复用
}
Semaphore
构造方法
/**
*因为这里需要有线程等待,需要使用到Lock,所有这里会有定义公平锁还是非公平锁,缺省是非公平锁
**/
public Semaphore(int permits, boolean fair) {//permits类似钥匙的个数
sync = fair ? new FairSync(permits) : new NonfairSync(permits);
}
acquire()
public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);//调用了AQS的方法
}
acquireSharedInterruptibly(1)
public final void acquireSharedInterruptibly(int arg)
throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
if (tryAcquireShared(arg) < 0)//tryAcquireShared(arg)就是减1,并判断state是否小于0
doAcquireSharedInterruptibly(arg);//小于0就入队
}
nonfairTryAcquireShared(int)
final int nonfairTryAcquireShared(int acquires) {
for (;;) {//自旋
int available = getState();//state的值
int remaining = available - acquires;//减1
if (remaining < 0 ||
compareAndSetState(available, remaining))//cas赋值
return remaining;
}
}
doAcquireSharedInterruptibly()
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
final Node node = addWaiter(Node.SHARED);//入AQS的同步队列,返回当前节点
boolean failed = true;
try {
for (;;) {
final Node p = node.predecessor();//取当前节点的前一个节点
if (p == head) {
int r = tryAcquireShared(arg);//再次判断state
if (r >= 0) {
setHeadAndPropagate(node, r);//如果r>0可以唤醒node节点的下一个节点
p.next = null; // 设置为空,因为已经获得了锁
failed = false;
return;
}
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())//挂起线程
throw new InterruptedException();
}
} finally {
if (failed)
cancelAcquire(node);
}
}
setHeadAndPropagate(Node node, int propagate)
private void setHeadAndPropagate(Node node, int propagate) {
Node h = head; // Record old head for check below
setHead(node);
if (propagate > 0 || h == null || h.waitStatus < 0 ||
(h = head) == null || h.waitStatus < 0) {
Node s = node.next;
if (s == null || s.isShared())
doReleaseShared();//唤醒当前节点的下一个节点
}
}
doReleaseShared();
private void doReleaseShared() {
for (;;) {
Node h = head;
if (h != null && h != tail) {
int ws = h.waitStatus;
if (ws == Node.SIGNAL) {
if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0))
continue; // loop to recheck cases
unparkSuccessor(h);//调用LockSupport.unPork()唤醒线程
}
else if (ws == 0 &&
!compareAndSetWaitStatus(h, 0, Node.PROPAGATE))
continue; // loop on failed CAS
}
if (h == head) // loop if head changed
break;
}
}
unparkSuccessor(h)
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
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)
LockSupport.unpark(s.thread);//实际调用的方法
}
release()释放锁
public void release() {
sync.releaseShared(1);
}
releaseShared(1)
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();//这个就是前文的方法,目的就是唤醒线程
return true;
}
return false;
}
tryReleaseShared(arg)
protected final boolean tryReleaseShared(int releases) {
for (;;) {//自旋
int current = getState();
int next = current + releases;//加1
if (next < current)
throw new Error("Maximum permit count exceeded");
if (compareAndSetState(current, next))//cas设置state
return true;
}
}
到此为止所有源码分析都结束了