java8以后使用CompletableFuture来支持异步编程,异步编程变得简单多了....
1-创建CompletableFuture对象
其中Async是以异步方式执行,run开头的都是得到没有返回值的CompletableFuture对象;以supply开头的可以拿到线程返回值;
public static CompletableFuture<Void> runAsync(Runnable runnable)
public static CompletableFuture<Void> runAsync(Runnable runnable,Executor executor)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier)
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
public static ExecutorService executorService = Executors.newFixedThreadPool(10);
public static void main01() {
System.out.println("main start....");
CompletableFuture.runAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 100 / 2;
System.out.println("运行结果:" + i);
}, executorService);
System.out.println("main end....");
}
/**
* runAsync创建CompletableFuture,不能获取返回值,因为返回值威Void
* 异步执行任务
* <p>
* <p>
* 输出结果:
* main start....
* main end....
* 当前线程:11
* 运行结果:50
*/
runAsync创建CompletableFuture,不能获取返回值,因为返回值威Void,异步执行任务...
public static void main02() throws Exception {
System.out.println("main start....");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 100 / 2;
System.out.println("运行结果:" + i);
return i;
}, executorService);
System.out.println("获取程序返回结果:" + future.get());//阻塞,等待获取结果
System.out.println("main end....");
}
/**
* supplyAsync创建CompletableFuture,能够获取程序返回结果
* 异步执行任务,获取返回结果
* <p>
* 输出结果:
* main start....
* 当前线程:11
* 运行结果:50
* 获取程序返回结果:50
* main end....
*/
supplyAsync创建CompletableFuture,能够获取程序返回结果
2-对象完成时对象回调方法
public CompletableFuture<T> whenComplete(BiConsumer<? super T, ? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action)
public CompletableFuture<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor)
public CompletableFuture<T> exceptionally(Function<Throwable, ? extends T> fn)
public static void main03() throws Exception {
System.out.println("main start....");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 100 / 2;
System.out.println("运行结果:" + i);
return i;
}, executorService).whenComplete((res, exp) -> {
System.out.println("异步执行完成了结果是:" + res + "--->异常是:" + exp);
});
System.out.println("获取程序返回结果:" + future.get());
System.out.println("main end....");
}
* whenComplete异步任务完成后,处理方式
* <p>
* 输出结果:
* main start....
* 当前线程:11
* 运行结果:50
* 异步执行完成了结果是:50--->异常是:null
* 获取程序返回结果:50
* main end....
public static void main03() throws Exception {
System.out.println("main start....");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 100 / 2;
System.out.println("运行结果:" + i);
return i;
}, executorService).whenComplete((res, exp) -> {
System.out.println("异步执行完成了结果是:" + res + "--->异常是:" + exp);
});
System.out.println("获取程序返回结果:" + future.get());
System.out.println("main end....");
}
* whenComplete异步任务完成后,处理方式
* <p>
* 输出结果:
* main start....
* 当前线程:11
* 运行结果:50
* 异步执行完成了结果是:50--->异常是:null
* 获取程序返回结果:50
* main end....
异常执行时,可以使用exceptionally
public static void main05() throws Exception {
System.out.println("main start....");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程:" + Thread.currentThread().getId());
int i = 100 / 0;
System.out.println("运行结果:" + i);
return i;
}, executorService).whenCompleteAsync((res, exp) -> {
System.out.println("异步执行完成了结果是:" + res + "--->异常是:" + exp);
}, executorService).exceptionally((exp) -> {
System.out.println("异步执行完成了异常是:" + exp.getMessage());
return 200;
});
System.out.println("获取程序返回结果:" + future.get());
System.out.println("main end....");
}
/**
* whenComplete异步任务完成后,异常处理方式
* <p>
* 输出结果:
* main start....
* 当前线程:13
* 异步执行完成了结果是:null--->异常是:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
* 异步执行完成了异常是:java.lang.ArithmeticException: / by zero
* 获取程序返回结果:200
* main end....
*/
3-对象完成时handle
handle方法:任务完成后处理,不管成功还是失败都可以接受,可以修改返回值
public <U> CompletableFuture<U> handle(BiFunction<? super T, Throwable, ? extends U> fn)
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn)
public <U> CompletableFuture<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor)
public static void main06() throws Exception {
System.out.println("main start....");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1:" + Thread.currentThread().getId());
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
int i = 100 / 0;
System.out.println("运行结果:" + i);
return i;
}, executorService).handle((res, exp) -> {
System.out.println("当前线程2:" + Thread.currentThread().getId());
System.out.println("异步执行完成了结果是:" + res + "--->异常是:" + exp);
if (exp != null) {
res = 200;
}
return res;
});
System.out.println("获取程序返回结果:" + future.get());
System.out.println("main end....");
}
/**
* whenComplete异步任务完成后,处理方式
* <p>
* 输出结果:
* main start....
* 当前线程1:13
* 当前线程2:13
* 异步执行完成了结果是:null--->异常是:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
* 获取程序返回结果:200
* main end....
*/
public static void main07() throws Exception {
System.out.println("main start....");
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1:" + Thread.currentThread().getId());
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
int i = 100 / 0;
System.out.println("运行结果:" + i);
return i;
}, executorService).handleAsync((res, exp) -> {
System.out.println("当前线程2:" + Thread.currentThread().getId());
System.out.println("异步执行完成了结果是:" + res + "--->异常是:" + exp);
if (exp != null) {
res = 200;
}
return res;
}, executorService);
System.out.println("获取程序返回结果:" + future.get());
System.out.println("main end....");
}
/**
* whenComplete异步任务完成后,处理方式
* <p>
* 输出结果:
* main start....
* 当前线程1:13
* 当前线程2:14
* 异步执行完成了结果是:null--->异常是:java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
* 获取程序返回结果:200
* main end....
*/
4-线程串行化方法
* thenApply:当一个线程依赖另外一个线程时,获取上一个任务返回结果,并且返回当前任务的返回值
public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn)
public <U> CompletableFuture<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor)
* thenAccept:消费处理结果,接受任务的处理结果,并消费处理,无返回值结果
public CompletableFuture<Void> thenAccept(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action)
public CompletableFuture<Void> thenAcceptAsync(Consumer<? super T> action,Executor executor)
* thenRun:只要上面任务执行完成就开始执行thenRun,执行thenRun后续操作
public CompletableFuture<Void> thenRun(Runnable action)
public CompletableFuture<Void> thenRunAsync(Runnable action)
public CompletableFuture<Void> thenRunAsync(Runnable action,Executor executor)
public static void main08_01() throws Exception {
System.out.println("main start....");
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1:" + Thread.currentThread().getId()+"->当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
int i = 100 / 10;
System.out.println("运行结果:" + i+"->当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
return i;
}, executorService).thenApplyAsync((resp) -> {
System.out.println("当前线程2:" + Thread.currentThread().getId()+"->当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程2执行完成"+"->当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
return resp+15;
}, executorService);
Integer result = completableFuture.get();
System.out.println("result="+result);
System.out.println("main end....");
}
/**
*
* main start....
* 当前线程1:11->当前时间:2023-02-06 11:22:07
* 运行结果:10->当前时间:2023-02-06 11:22:12
* 当前线程2:12->当前时间:2023-02-06 11:22:12
* 线程2执行完成->当前时间:2023-02-06 11:22:15
* result=25
* main end....
*/
public static void main09() throws Exception {
System.out.println("main start....");
CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1:" + Thread.currentThread().getId() + "->当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
int i = 100 / 10;
System.out.println("运行结果:" + i + "->当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
return i;
}, executorService).thenAcceptAsync((res) -> {
System.out.println("当前线程2:" + Thread.currentThread().getId() + "->当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
System.out.println("上一个线程的结果:" + res*50);
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程2执行完成" + "->当前时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}, executorService);
completableFuture.get();
System.out.println("main end....");
}
/**
* thenAcceptAsync
* <p>
* 输出结果:
main start....
当前线程1:13->当前时间:2021-10-18 11:08:38
运行结果:10->当前时间:2021-10-18 11:08:43
当前线程2:14->当前时间:2021-10-18 11:08:43
上一个线程的结果:500
线程2执行完成->当前时间:2021-10-18 11:08:46
main end....
*/
public static void main08() throws Exception {
System.out.println("main start....");
CompletableFuture<Void> completableFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程1:" + Thread.currentThread().getId()+"->当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
}
int i = 100 / 10;
System.out.println("运行结果:" + i+"->当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
return i;
}, executorService).thenRunAsync(() -> {
System.out.println("当前线程2:" + Thread.currentThread().getId()+"->当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程2执行完成"+"->当前时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
}, executorService);
completableFuture.get();
System.out.println("main end....");
}
/**
* thenRunAsync
* <p>
* 输出结果:
main start....
当前线程1:13->当前时间:2021-10-18 11:04:28
运行结果:10->当前时间:2021-10-18 11:04:33
当前线程2:14->当前时间:2021-10-18 11:04:33
线程2执行完成->当前时间:2021-10-18 11:04:36
main end....
*/