有时,我们需要测试一下,对某个任务,我们在分配N个线程数并行执行,共计需要多少时间。如果我们在使用for循环,分配线程后,立即执行已分配的线程,则先分配的线程,可能会“领先”后分配的线程执行完成,且线程之间对CPU的竞争成度,活跃线程数均会变化。故,最好的方法是,让所有线程同时开始执行。这就需要我们使用同步工具类“闭锁” CountDownLatch 来控制线程的起始终止。
CountDownLatch 工具 中含有一个计数器,主要提供2个方法:
countDown() 将计数器减一。
await():用于等待计数器达到0,随后可允许线程执行.如果计数器始终不为0,则await()会一直阻塞,直到计数器达到0.
具体代码如下:
package com.myConcurrent.demo.concurrentUtils;
import java.util.concurrent.CountDownLatch;
/**
* @author fenghongyu
*/
public class CountDownLatchDemo {
public void getRunTime(){
//线程准备阶段
int threadNum = 3;
CountDownLatch startGate = new CountDownLatch(1);
CountDownLatch endGate = new CountDownLatch(threadNum);
for(int i=0;i<threadNum;i++){
new Thread(() -> {
try {
startGate.await(); //启动门等待计数器达到0,如果一直不到0,则一直等待。
calcution();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
endGate.countDown(); //结束门计数减一,表示该任务已准备就绪,等待开始执行。
}
}).start();
}
//线程准备完毕,准备启动
long startTime = System.nanoTime();
startGate.countDown(); //启动门计数减1,使得计数器达到0,启动线程
try {
endGate.await(); // 主线程,等待所有线程都执行完 endGate.countDown();使计数器达到0,表示所有线程都计算完毕。
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.nanoTime();
System.out.println(endTime-startTime);
}
//某个计算任务
public void calcution() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
CountDownLatchDemo demo = new CountDownLatchDemo();
demo.getRunTime();
}
}