da
对于多任务耗时的业务场景,一般我们会用到线程异步处理,在以前我们用 Thread 或者 Runnable 来实现异步,这是oracle官方做法,不过缺点很明显
对于复杂业务场景需要配置线程池
代码繁杂,对于新手容易造成不必要的bug
如果涉及到线程锁或线程通讯就棘手了
现在,java8为我们提供了CompletableFuture类,可以完全解决以上问题。
异步api代码如下:
runAsync() 异步无参返回
supplyAsync() 异步有参返回
allOf() 多个异步处理(针对有参返回)
anyOf() 多个异步随机处理(针对有参返回)
forEach循环
package cn.opendatachain.manage;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* SupplyAsyncTests Description
*
* @author lishijian
* @version odc-manage 1.0.0.RELEASE
* <b>Creation Time:</b> 2021/7/9 10:17
*/
@Slf4j
@SpringBootTest
public class SupplyAsyncTests {
/**
* runAsync() 异步无参返回
* @throws Exception
*/
@Test
public void asyncThread()throws Exception{
CompletableFuture async1 = CompletableFuture.runAsync(()->{
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
System.out.println("none return Async");
}catch (Exception e){
e.printStackTrace();
}
});
// 调用get()将等待异步逻辑处理完成
System.out.println("111111111111111111111111111111111");
async1.get();
System.out.println("222222222222222222222222222222222");
}
/**
* 输出结果:
*
* 111111111111111111111111111111111
* ForkJoinPool.commonPool-worker-19
* none return Async
* 222222222222222222222222222222222
*/
//----------------------------------------------------------------------------------------------------------------
/**
* supplyAsync() 异步有参返回
* @throws Exception
*/
@Test
public void asyncThread2()throws Exception{
CompletableFuture async2 = CompletableFuture.supplyAsync(()->{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "hello";
});
System.out.println("111");
/**
* 最多等待这个未来的给定时间,如果完成返回结果,超时抛出TimeoutException
* get(timeout ,unit)
* @param timeout等待的最长时间
* @param unit超时参数的时间单位
*/
String result2 = (String)async2.get(3L, TimeUnit.SECONDS);
System.out.println("222");
//等待异步操作完成,然后返回其结果。
String result = (String)async2.get();
System.out.println("333");
System.out.println(result);
System.out.println(result2);
}
/**
* 输出结果:
* 111
* 222
* 333
* hello
* hello
*/
//----------------------------------------------------------------------------------------------------------------
/**
* allOf() 多个异步处理(针对有参返回)
* 注意:CompletableFuture 一定要给类型,否则无法识别
* @throws Exception
*/
@Test
public void asyncThread3()throws Exception{
CompletableFuture a = CompletableFuture.supplyAsync(() -> "hello");
CompletableFuture b = CompletableFuture.supplyAsync(() -> "youth");
CompletableFuture c = CompletableFuture.supplyAsync(() -> "!");
CompletableFuture all = CompletableFuture.allOf(a,b,c);
all.get();
String collect = Stream.of(a, b, c).map(CompletableFuture<String>::join).collect(Collectors.joining(" "));
System.out.println(collect);
}
/**
* 输出结果:
* hello youth !
*/
//----------------------------------------------------------------------------------------------------------------
/**
* anyOf() 多个异步随机处理(针对有参返回)
* @throws Exception
*/
@Test
public void asyncThread4()throws Exception{
CompletableFuture a = CompletableFuture.supplyAsync(() ->{
try{
Thread.sleep(20);
return "hello";
}catch (Exception e){
e.printStackTrace();
return "none~";
}
});
System.out.println("1111");
CompletableFuture b = CompletableFuture.supplyAsync(() -> "youth");
CompletableFuture c = CompletableFuture.supplyAsync(() -> "!");
CompletableFuture any = CompletableFuture.anyOf(a,b,c);
System.out.println("2222");
String result = (String)any.get();
System.out.println("3333");
System.out.println(result);
}
/**
* 输出结果:
* 1111
* 2222
* 3333
* youth
*/
//----------------------------------------------------------------------------------------------------------------
//forEach对List的循环样例
@Test
public void listForeach(){
List<String> lst = new ArrayList(5){{
add("A");
add("B");
add("H");
add("O");
add("M");
}};
lst.forEach(System.out::println);
lst.forEach((item)-> System.out.println(item.concat("_")));
}
//forEach对数组的循环 样例
@Test
public void arrForeach(){
String[] strArr = new String[]{"A","B","C","D"};
Arrays.stream(strArr).forEach(System.out::println);
}
//forEach对int范围的循环(包括头不包括尾) 样例
@Test
public void numericForeach(){
IntStream.range(0,10).forEach(System.out::println);
}
//forEach对Map的循环 样例:
@Test
public void mapForeach(){
Map<String,Object> mps = new HashMap(5){{
put("a",1);
put("b",true);
put("c",23.44F);
put("d","hello");
put("e",11L);
}};
mps.forEach((k,v)-> System.out.println(k.concat(":").concat(String.valueOf(v))));
}
}