针对 - 单任务无返回值,单任务有返回值,多任务无返回值,多任务有返回值 4种大情况
加上 - 线程池直接提交和使用CompletableFuture 两种方式实现
package juc.task4All;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;
/**
* 线程池实现各种不同任务的方式
*/
public class TaskForAll {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// ThreadPoolExecutor threadPool = ThreadPoolSingle.getInstance();
ExecutorService threadPool = Executors.newCachedThreadPool();
/**
* case1: 单一任务无返回值,直接提交
*/
threadPool.execute(() -> {
getVoid();
}); //execute
threadPool.submit(() -> {
getVoid();
}); //submit
CompletableFuture.runAsync(() -> { //CompletableFuture 异步编排
getVoid();
}, threadPool);
System.out.println("================================================");
/**
* case2: 多个任务无返回值
* 2.1:异步后,无需等待,主线程继续执行,按照case1提交即可
* 2.2:异步后,等待执行完毕,主线程才能继续执行
*/
//2.2 -1 CountDownLatch 任务相同可以使用for循环 或者任务不同时,单独调用
CountDownLatch downLatch = new CountDownLatch(5);
System.out.println("开始循环,countDownLatch值为: " + downLatch.getCount());
for (int i = 0; i < 5; i++) {
threadPool.execute(() -> {
try {
getVoid();
} finally {
downLatch.countDown();
}
});
}
System.out.println("等待中,countDownLatch值为: " + downLatch.getCount());
downLatch.await();
System.out.println("等待结束,countDownLatch值为: " + downLatch.getCount() + " ,主程序继续执行..");
System.out.println("================================================");
//2.2-2 CompletableFuture
CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(() -> {
getVoid();
}, threadPool);
CompletableFuture<Void> completableFuture2 = CompletableFuture.runAsync(() -> {
getVoid();
}, threadPool);
System.out.println("allOf之前。。。 等待?");
CompletableFuture.allOf(completableFuture1, completableFuture2).get();
System.out.println("allOf之后。。。 ");
//当然也可以list构造一个数组,传给allOf
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
CompletableFuture[] cs = list.stream().map(integer -> {
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
getVoid();
}, threadPool);
return completableFuture;
}).toArray(CompletableFuture[]::new);
System.out.println("allOf之前。。。 等待?");
CompletableFuture.allOf(cs).get();
System.out.println("allOf之后。。。 ");
//for循环
List<CompletableFuture> completableFutureList = new ArrayList<>();
for (int j = 0; j < 5; j++) {
completableFutureList.add(CompletableFuture.runAsync(() -> {
getVoid();
}, threadPool));
}
CompletableFuture[] cfs = completableFutureList.toArray(new CompletableFuture[completableFutureList.size()]);
System.out.println("开始等待...");
CompletableFuture.allOf(cfs).get(); //拿不到返回值
System.out.println("等待结束...");
System.out.println("================================================");
/**
*case:3 单个任务有返回值 -- 拿到结果后继续执行
*/
Future<String> future = threadPool.submit(() -> {
String target = getTarget();
return target;
});
System.out.println("开始阻塞等待。。。");
String s1 = future.get();//阻塞等待获取,继续执行主程序
System.out.println("继续执行主程序。。。" + s1);
CompletableFuture<String> supplyAsync = CompletableFuture.supplyAsync(() -> {
String target = getTarget();
return target;
}, threadPool);
System.out.println("开始阻塞等待。。。");
String s2 = supplyAsync.get();
System.out.println("继续执行主程序。。。" + s2);
//这里也可以拿到结果继续用CompletableFuture处理
supplyAsync.whenComplete((u,e)->{ //主线程处理
System.out.println("结果" + u);
System.out.println("异常" + e);
});
supplyAsync.whenCompleteAsync((u,e)->{ //异步线程池继续处理
System.out.println("Thread.currentThread().getId() = " + Thread.currentThread().getId());
System.out.println("结果" + u);
System.out.println("异常" + e);
},threadPool);
System.out.println("=================case:4 多个任务有返回值============================");
/**
*case:4 多个任务有返回值 -- 拿到结果后继续执行
*/
List<Future> taskList = new ArrayList<>();
Future<String> submit1 = threadPool.submit(() -> {
return getTarget() + " 1";
});
taskList.add(submit1);
Future<String> submit2 = threadPool.submit(() -> {
return getTarget() + " 2";
});
taskList.add(submit2);
Future<String> submit3 = threadPool.submit(() -> {
return getTarget() + " 3";
});
taskList.add(submit3);
// System.out.println("taskList.get(0).get() = " + taskList.get(0).get());
// System.out.println("taskList.get(1).get() = " + taskList.get(1).get());
// System.out.println("taskList.get(2).get() = " + taskList.get(2).get());
//or --------------这里也可以写到for循环里面然后遍历get
System.out.println("submit1 = " + submit1.get());
System.out.println("submit2 = " + submit2.get());
System.out.println("submit3 = " + submit3.get());
CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
return getTarget() + " 1";
}, threadPool);
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
return getTarget() + " 2";
}, threadPool);
CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
return getTarget() + " 3";
}, threadPool);
System.out.println(future1.get());
System.out.println(future2.get());
System.out.println(future3.get());
//for循环
List<CompletableFuture> futureList = new ArrayList<>();
for (int j = 0; j < 5; j++) {
futureList.add(
CompletableFuture.supplyAsync(() -> {
return getTarget() + " 3";
}, threadPool)
.thenApply(s -> {
System.out.println("s = " + s);
return s + "1";
})
.whenComplete((u, e) -> {
System.out.println("u = " + u); //归约到最后么有返回值才能用allOf
})
);
}
CompletableFuture[] cfss = futureList.toArray(new CompletableFuture[futureList.size()]);
System.out.println("开始等待...有返回值的for");
CompletableFuture.allOf(cfss).get(); //拿不到返回值
System.out.println("等待结束...有返回值的for");
}
public static String getTarget() {
System.out.println(" this is a returned method... threadId = " + Thread.currentThread().getId());
System.out.println("threadId = " + Thread.currentThread().getId());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return " getTarget's return string ";
}
public static void getVoid() {
System.out.println(" this is a void method... threadId = " + Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}