用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。
方法 | 意义 |
---|---|
void await() | 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。 |
boolean await(long timeout, TimeUnit unit) | 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。 |
void countDown() | 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。 |
long getCount() | 返回当前计数。 |
String toString() | 返回标识此锁存器及其状态的字符串。 |
重点是countDown(),执行之后,计数器减一,而await会一直等待,直到计数器为0,需要注意的是这个计数器不可以被重置。
应用:
测试AtomicInteger和Synchronized的效率问题
public class TestAtomicInteger
{
private static int id = 0;
private static AtomicInteger atomicID = new AtomicInteger();
private static CountDownLatch latch = null;
public static void main(String[] args) throws InterruptedException
{
System.out.println("Hello World!");
latch = new CountDownLatch(50);
long start = System.nanoTime();
for(int i = 0; i < 50 ; i ++){
new Thread(new Task(false)).start();
}
latch.await();//等待50个线程都执行完
System.out.println("Sychronized style consume time:" + (System.nanoTime()-start)/1000000.0);
latch = new CountDownLatch(50);
start = System.nanoTime();
for(int i = 0; i < 50 ; i ++){
new Thread(new Task(true)).start();
}
latch.await();
System.out.println("CAS style consume time:" + (System.nanoTime()-start)/1000000.0);
}
public synchronized static int getNextID(){
return ++id;
}
public static int getNextIDWithAtomic(){
return atomicID.incrementAndGet();
}
static class Task implements Runnable
{
private boolean isAtomic ;
public Task(boolean isAtomic){
this.isAtomic = isAtomic;
}
public void run(){
for(int i = 0; i < 1000; i ++){
if(isAtomic){
getNextIDWithAtomic();
}else{
getNextID();
}
}
latch.countDown();//执行完一个任务计数器减一
}
}
}