CountDownLatch
latch翻译:门闩; 插销; 碰锁; 弹簧锁;
理解为倒数的门闩(共享锁)
public class Demo {
public static CountDownLatch cdl = new CountDownLatch(5);
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("on your mark!" + Thread.currentThread().getName());
cdl.countDown();
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("run!");
}
}).start();
}
}
}
执行结果
on your mark!Thread-0
on your mark!Thread-1
on your mark!Thread-2
on your mark!Thread-3
on your mark!Thread-4
run!Thread-4
run!Thread-0
run!Thread-2
run!Thread-3
run!Thread-1
构造方法
须传入>0的整型count
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
inner class Sync
为CountDownLatch的内部类,继承自AbstractQueuedSynchronizer(AQS)
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;
Sync(int count) {
setState(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
protected boolean tryReleaseShared(int releases) {
// Decrement count; signal when transition to zero
// 倒计数;当倒计数到0时,通知所有线程
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
// CAS操作
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
}
await()
使当前线程进入阻塞状态,直到计数器通过countDown()方法倒数至零
await(long timeout, TimeUnit unit)
使当前线程进入阻塞状态,直到计数器通过countDown()方法倒数至零,或设置的时间耗尽
countDown()
递减计数,类似于发令枪前的倒数计时,当数到0时,释放所有处于waiting的线程
/**
* Decrements the count of the latch, releasing all waiting threads if
* the count reaches zero.
*
* <p>If the current count is greater than zero then it is decremented.
* If the new count is zero then all waiting threads are re-enabled for
* thread scheduling purposes.
*
* <p>If the current count equals zero then nothing happens.
* <p>当前计数若已经为0了,则不会发生任何事情
*/
public void countDown() {
sync.releaseShared(1);
}
/**
* Releases in shared mode. Implemented by unblocking one or more
* threads if {@link #tryReleaseShared} returns true.
*
* @param arg the release argument. This value is conveyed to
* {@link #tryReleaseShared} but is otherwise uninterpreted
* and can represent anything you like.
* @return the value returned from {@link #tryReleaseShared}
*/
public final boolean releaseShared(int arg) {
if (tryReleaseShared(arg)) {
doReleaseShared();
return true;
}
return false;
}
注意
- CountDownLatch的计数不能回退重置
网友评论