import java.util.concurrent.CountDownLatch;
public class test {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(3);
new Thread(()->{
countDownLatch.countDown();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
new Thread(()->{
countDownLatch.countDown();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
new Thread(()->{
countDownLatch.countDown();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
//主线程等待3--->0
countDownLatch.await();
}
}
使用
一般是主线程等待countDown减为0,上图3个线程每个都会调用countDownLatch.countDown()方法是Latch-1,减为0唤醒主线程
与join的区别
join也可以完成等待线程运行结束再继续执行,但是在实际项目中,用户线程一般是从线程池获取的,不会轻易结束,并且调用join必须知道对应线程的变量名。而用CountDownLatch可以灵活的通知等待线程,扩展性更强
模拟10人游戏加载成功主程序加载完成
public class GameTest {
public static void main(String[] args) throws InterruptedException {
Random random = new Random();//单独线程随机休眠一段时间,模拟随机加载
ExecutorService pool = Executors.newFixedThreadPool(10);//初始化线程池
CountDownLatch countDownLatch = new CountDownLatch(10);//初始化CountDownLatch,每有一个线程完成,--
String[] all=new String[10];//显示的结果-----进度条
for (int j = 0; j < 10; j++) {
int finalJ = j;
pool.submit(()->{
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(random.nextInt(100));
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
all[finalJ]=i+"%";
System.out.print("\r"+ Arrays.toString(all));//print不换行,一行打印 "\r"覆盖之前的内容
}
countDownLatch.countDown();//计数减一
});
}
countDownLatch.await();//主线程等待各个线程完成
System.out.println("游戏加载完成.............................");
}
}