多线程所有子线程执行完后再执行主线程。
方法一:
使用CountDownLatch 计数器
public static void main(String[] args) throws Exception {
int N = 10;// 线程个数
CountDownLatch countDownLatch = new CountDownLatch(N);// 实例化一个倒计数器,N指定计数个数
for (int i = 0; i < N; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("子线程结束");
countDownLatch.countDown(); // 计数减一
}
}
}).start();
}
countDownLatch.await();// 阻塞,等待当计数减到0时,执行后面的代码
System.out.println("结束");
}
方法二:
使用线程池
public static void main(String[] args) throws Exception {
int N = 10;// 线程个数
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(N);
for (int i = 0; i < N; i++) {
fixedThreadPool.submit(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("子线程结束");
}
}
});
}
//停止接收外部submit的任务
fixedThreadPool.shutdown();
// 等待子线程结束,再继续执行下面的代码
fixedThreadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);//阻塞,等待所有子线程执行完成
System.out.println("结束");
}
模拟并行执行
使用CountDownLatch 计数器,模拟并行执行一个代码段
public class Test {
private static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS");
public static void main(String[] args) throws Exception {
Random random = new Random();
int N = 10;// 线程个数
CountDownLatch countDownLatch = new CountDownLatch(N);// 实例化一个倒计数器,N指定计数个数
for (int i = 0; i < N; i++) {
new Thread(new Runnable() {
@Override
public void run() {
try {
int t = random.nextInt(N);//随机数
System.out.println("随机睡眠:" + t + "秒");
Thread.sleep(t * 1000);
countDownLatch.countDown(); // 计数减一
countDownLatch.await();// 阻塞,等待当计数减到0时,执行后面的代码
//并发执行打印方法
print();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
private static void print() {
String time = LocalDateTime.now().format(dateTimeFormatter);
System.out.println("并行代码执行时间:" + time);
}
}