@Test
public void test07(){
Person zhagnsan = new Person("zhagnsan", 18);
Person lisi = new Person("lisi", 19);
List<Person> firstList = Lists.newArrayList(zhagnsan, lisi);
Person wangwu = new Person("wangwu", 22);
Person zhaoliu = new Person("zhaoliu", 27);
List<Person> secondList = Lists.newArrayList(wangwu, zhaoliu);
List<Person> newNameList = firstList;
List<CompletableFuture<Integer>> taskList = Lists.newArrayList();
CompletableFuture<Integer> cf1 = getIntegerCompletableFuture(newNameList);
taskList.add(cf1);
newNameList = secondList;
CompletableFuture<Integer> cf2 = getIntegerCompletableFuture(newNameList);
taskList.add(cf2);
zhagnsan.setAge(80);
taskList.forEach(task -> {
final Integer result = task.join();
System.out.println(result);
});
}
private CompletableFuture<Integer> getIntegerCompletableFuture(List<Person> newNameList) {
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
System.out.println("cf: " + newNameList);
newNameList.clear();
return 1;
});
}
运行结果:
cf: [{"age":22,"name":"wangwu"}, {"age":27,"name":"zhaoliu"}]
cf: [{"age":80,"name":"zhagnsan"}, {"age":19,"name":"lisi"}]
1
1
可以开一个线程等待任务线程结果,让主线程提前返回
// 开一个异步线程等待任务完成后执行汇总任务, 让主线程提前返回结果
// 注意: 如果此处指定threadPool, 确保主方法提前返回后,threadPool不要shutdown和awaitTermination
// 使用thenRunAsync() 调用的是ForkJoinPool.commonPool-worker-1
// 使用thenRun() 调用的是pool-1-thread-1
CompletableFuture.allOf(taskList.toArray(new CompletableFuture[0]))
.thenRun(() -> {
try {
Thread.sleep(10 * 60 * 1000);
} catch (InterruptedException e) {
}
List<Integer> resultList = taskList.stream().map(CompletableFuture::join).collect(Collectors.toList());
System.out.println(Thread.currentThread().getName());
System.out.println(resultList);
System.out.println("game over");
});
建议:
1. 传给线程运行的参数是常量
2. 传给线程运行的参数不是常量,请不要在其他线程修改
3. 若多线程修改同一数据源,请使用其他手段保持数据一致性
4. 可以传入数据副本到线程中,隔绝影响,深度克隆该对象(反序列化)