在开发过程当中,我们使用了多线程来异步执行多任务,但是我们想在这些任务执行完成后,才接着再执行的话,就需要使用到CountDownLatch这个类了。
首先我们需要知道被执行任务的个数,比如这里是有20个任务,那么
CountDownLatch latch = new CountDownLatch(20);
然后在创建任务的时候,把latch带进去,在该任务的run()方法执行完毕后,需要执行latch.countDown()方法。这个countDown()方法就标识这个任务执行完了,总的数量会减1.
这里为了确保任务出异常的时候,任务总数也要减少1,所以需要规范写法:
public class Task implements Runnable {
@Override
public void run() {
try{
//执行任务
}catch(){
//处理异常
}finally{
//任务总数减去1
latch.countDown();
}
}
}
在外面使用latch.await();来等待全部线程执行完毕,只有全部线程执行完毕后,这里的latch.await()才会往后面执行,不然的话,一直卡在这里。
示例代码:
任务类:
package com.tianrun.utils;
import java.util.concurrent.CountDownLatch;
public class Task implements Runnable {
private int num;
//线程计数
private CountDownLatch latch;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Task(int num, CountDownLatch latch) {
this.num = num;
this.latch=latch;
}
@Override
public void run() {
try{
if(num==5){
throw new RuntimeException("error");
}
System.out.println(num);
}catch (Exception e){
System.out.println(e.getMessage());
}finally {
latch.countDown();
}
}
}
调用:
package com.tianrun.utils;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
public class TestThreadCount {
public static void main(String[] args) {
//这里是所有任务的个数
CountDownLatch latch = new CountDownLatch(10);
for(int i=0;i<10;i++){
//创建任务的时候,把latch也传递进去,反正任务里面执行完毕都会去latch.countDown()
Executors.newSingleThreadExecutor().execute(new Task(i,latch));
}
try {
latch.await();
System.out.println("test over");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}