public class CountDownLatch {
/**
* Synchronization control For CountDownLatch.
* Uses AQS state to represent count.
*/
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374 L;
Sync(int count) {
setState(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared (int acquires) {
return (getState() == 0 ) ? 1 : -1 ;
}
protected boolean tryReleaseShared (int releases) {
for (;;) {
int c = getState();
if (c == 0 )
return false ;
int nextc = c-1 ;
if (compareAndSetState(c, nextc))
return nextc == 0 ;
}
}
}
private final Sync sync;
public CountDownLatch (int count) {
if (count < 0 ) throw new IllegalArgumentException("count < 0" );
this .sync = new Sync(count);
}
public void await () throws InterruptedException {
sync.acquireSharedInterruptibly(1 );
}
public boolean await (long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1 , unit.toNanos(timeout));
}
public void countDown () {
sync.releaseShared(1 );
}
public long getCount () {
return sync.getCount();
}
public String toString () {
return super .toString() + "[Count = " + sync.getCount() + "]" ;
}
}
public class Main {
static class Runner implements Runnable {
private CountDownLatch cdlatch;
private String name;
public Runner (String name, CountDownLatch cdlatch) {
this .name = name;
this .cdlatch = cdlatch;
}
@Override
public void run () {
try {
Thread.sleep(100 * (new Random()).nextInt(100 ));
System.out .println(name + "出发." );
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out .println(name + "到达目的地." );
cdlatch.countDown();
}
}
public static void main (String[] arg) {
CountDownLatch cdlatch = new CountDownLatch(3 );
Thread t1 = new Thread(new Runner("1号" ,cdlatch));
Thread t2 = new Thread(new Runner("2号" ,cdlatch));
Thread t3 = new Thread(new Runner("3号" ,cdlatch));
t1.start();
t2.start();
t3.start();
try {
cdlatch.await ();
}catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out .println("finished" );
}
}