CountDownLatch
、 CyclicBarrier
、 Future.get()
、 Completable.allOf()
。
public class WaitThreadsDemo {
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 100L,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy());
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
int index = i;
executor.submit(() -> {
System.out.println("子线程" + index);
});
}
System.out.println("主线程-----");
}
}
结果如下:
子线程0
子线程3
子线程5
主线程-----
子线程1
子线程7
子线程8
子线程9
子线程6
子线程4
子线程2
public class WaitThreadsDemo {
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 100L,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy());
public static void main(String[] args) throws InterruptedException {
long start = System.currentTimeMillis();
CountDownLatch count = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
int index = i;
executor.submit(() -> {
try {
Thread.sleep(200);
System.out.println("子线程" + index);
count.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
count.await();
System.out.println("主线程-----");
long end = System.currentTimeMillis();
System.out.println("花费时间:" + (end - start));
}
}
结果如下:
子线程4
子线程1
子线程0
子线程2
子线程3
子线程9
子线程5
子线程6
子线程7
子线程8
主线程-----
花费时间:493
public class WaitThreadsDemo {
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 100L,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy());
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
long start = System.currentTimeMillis();
CyclicBarrier cyclicBarrier = new CyclicBarrier(11);
for (int i = 0; i < 10; i++) {
int index = i;
executor.submit(() -> {
try {
Thread.sleep(200);
System.out.println("子线程running" + index);
cyclicBarrier.await();
System.out.println("子线程end***" + index);
} catch (Exception e) {
e.printStackTrace();
}
});
}
System.out.println("主线程running@@@");
cyclicBarrier.await();
System.out.println("主线程end-----");
long end = System.currentTimeMillis();
System.out.println("花费时间:" + (end - start));
}
}
结果如下:
主线程running@@@
子线程running5
子线程running7
子线程running6
子线程running8
子线程running9
子线程running1
子线程running0
子线程running2
子线程running3
子线程running4
子线程end***4
主线程end-----
花费时间:289
子线程end***6
子线程end***5
子线程end***7
子线程end***8
子线程end***0
子线程end***3
子线程end***2
子线程end***9
子线程end***1
由代码和执行结果可以看出:
await()
await()
)await()
)后的操作,所以子线程调用await()要放在最后public class WaitThreadsDemo {
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 100L,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy());
public static void main(String[] args) throws InterruptedException, BrokenBarrierException {
long start = System.currentTimeMillis();
CyclicBarrier cyclicBarrier = new CyclicBarrier(5, () -> {
System.out.println("主线程end----");
long end = System.currentTimeMillis();
System.out.println("花费时间:" + (end - start));
});
for (int i = 0; i < 10; i++) {
int index = i;
executor.submit(() -> {
try {
Thread.sleep(200);
System.out.println("子线程running" + index);
cyclicBarrier.await();
System.out.println("子线程end***" + index);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
}
CountDownLatch
表示所有子线程一个一个执行完毕,子线程执行完之前主线程阻塞。CyclicBarrier
表示所有子线程全部到达一个障碍屏障前,然后一起执行完毕,和主线程无关。CountDownLatch
基于AQS
实现,CyclicBarrier
基于ReenTrantLock
+ Condition
实现CountDownLatch
每次countDown()
减一表示一个参赛者冲过终点线,全部通过,比赛结束。CyclicBarrier
相当于在终点线前设置一个障碍,所有参赛者到达障碍前,然后撤掉障碍手拉手通过终点线。CyclicBarrier
的复用就跟“车满发车”一个道理,乘客陆续上车,车满发车。public class WaitThreadsDemo {
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 100L,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy());
public static void main(String[] args) throws InterruptedException, ExecutionException {
long start = System.currentTimeMillis();
List<Future> futureList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
int index = i;
Future future = executor.submit(() -> {
try {
Thread.sleep(200);
System.out.println("子线程running" + index);
} catch (Exception e) {
e.printStackTrace();
}
});
futureList.add(future);
}
for (Future future : futureList) {
//监听线程池子线程执行状态及执行结果。
future.get();
}
System.out.println("主线程end-----");
long end = System.currentTimeMillis();
System.out.println("花费时间:" + (end - start));
}
}
结果如下
子线程running7
子线程running4
子线程running6
子线程running5
子线程running1
子线程running3
子线程running2
子线程running8
子线程running9
子线程running0
主线程end-----
花费时间:303
public class WaitThreadsDemo {
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 100L,
TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new ThreadPoolExecutor.CallerRunsPolicy());
public static void main(String[] args) throws InterruptedException, ExecutionException {
long start = System.currentTimeMillis();
List<CompletableFuture> futureList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
int index = i;
CompletableFuture<String> future = CompletableFuture.supplyAsync(()->{
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
//模拟两次异常
if (index % 7 ==0){
int tmp = index/0;
}
System.out.println("子线程running" + index);
return "success";
},executor).exceptionally(e-> e.getMessage());
futureList.add(future);
}
//allOf()等待所有线程执行完毕
CompletableFuture<Void> allFutures = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()]));
//但是allOf()拿不到执行结果,需要再次回调获取结果
CompletableFuture<List<String>> finalFutures = allFutures.thenApply(v-> futureList.stream().map(CompletableFuture<String>::join).collect(Collectors.toList()));
System.out.println(finalFutures.get());
//也可以直接使用最初的futureList集合获取结果,如下两行:
//List resultList = futureList.stream().map(CompletableFuture::join).collect(Collectors.toList());
//System.out.println(resultList);
System.out.println("主线程end-----");
long end = System.currentTimeMillis();
System.out.println("花费时间:" + (end - start));
}
}
结果如下:
子线程running6
子线程running5
子线程running4
子线程running3
子线程running2
子线程running1
子线程running9
子线程running8
[java.lang.ArithmeticException: / by zero, success, success, success, success, success, success, java.lang.ArithmeticException: / by zero, success, success]
主线程end-----
花费时间:313
allOf()
没有返回值,拿不到执行结果,需要再次使用回调函数获取最初futureList
的执行结果。其实可以直接遍历futureList
获取结果。
CompletableFuture
的详细使用:CompletableFuture使用详解