Java异步任务编排

多线程创建的五种方式:

  1. 继承Thread类
  2. 实现runnable接口。
  3. 实现Callable接口 + FutureTask(可以拿到返回结果,阻塞式等待。)
  4. 线程池创建。
ExcutorService service = Excutors.newFixedThreadPool(10);
service.excute(new Runnable01());
  1. 另外一种创建线程池的方式:
ThreadPoolExecutor executor = new ThreadPoolExcutor();

// 七大参数:
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime:线程最大回收时间。即线程空闲的最大时间。超过该时间就销毁。
unit:时间单位。回收线程的时间的单位。
workQueue:阻塞队列。当核心线程数满了,剩余的线程将在阻塞队列中等待。
threadFactory:创建线程的工厂。
RejectedExecutionHandler:核心线程满了,阻塞队列中也满了,同时额外建立的非核心线程数(最大线程数-核心线程数)也都用完了,此时将采取拒绝策略。
max都执行完成,有很多空闲。在指定的时间keepAliveTime以后,就会释放max-core这些线程。
LinkedBlockingQueue:默认大小是Integer的最大值。可能导致内存不足。
// 核心线程数为0 , 非核心线程数是Integer的最大值。所有线程都可回收。
Executors.newCachedThreadPool();

// 固定线程池,核心线程数和最大线程数一样,都是传入的值。  核心=最大,都一直不会回收
Executors.newFixedThreadPool(10);

// 做定时任务调度的线程池。
Executors.newScheduledThreadPool(10);

// 单线程的线程池,后台从队列中获取任务,挨个执行。
Executors.newSingleThreadExecutor()

异步编排

创建异步编排对象

CompletableFuture.runAsync(() -> {
    
} , executorService);


CompletableFuture.supplyAsync(() -> {

} , executorService);

supply开头:这种方法,可以返回异步线程执行之后的结果
run开头:这种不会返回结果,就只是执行线程任务

  • CompletableFuture.whenComplete():感知异步线程的执行结果。但是无法返回。
  • CompletableFuture.exceptionally():处理异常,只要有异常,会进入该方法处理。然后返回一个对应的结果。
  • CompletableFuture.handle():用于处理返回结果,可以接收返回值和异常,可以对返回值进行修改。
CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
    return "hello";
}, executorService).whenCompleteAsync((res , throwable) -> {
    System.out.println("stringCompletableFuture whenCompleteAsync:" + res);
    throw new RuntimeException("hhhhhh");
}, executorService).exceptionally((throwable) -> {
    return "jimo";
});

System.out.println("stringCompletableFuture:" + stringCompletableFuture.get());

线程串行方法

CompletableFuture.supplyAsync(() -> {
    return 1;
},executorService).thenRunAsync(() -> {
    System.out.println("串行化执行。。。。");
} , executorService);
CompletableFuture.supplyAsync(() -> {
    return "n";
} , executorService).thenAcceptAsync((res) -> {
    System.out.println(res + "串行化:执行结果:" + res);
});
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
    return "急急急";
}, executorService).thenApplyAsync((res) -> {
    return "ddd" + res;
});
System.out.println(future.get());
// 使线程串行执行,不感知上一线程执行的结果,也不返回当前线程执行的结果。
public CompletableFuture<Void> thenRun(Runnable action);
public CompletableFuture<Void> thenRunAsync(Runnable action);
public CompletableFuture<Void> thenRunAsync(Runnable action, Executor executor);

// 使线程串行执行,感知上一线程执行的结果,不返回当前线程执行的结果。
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);

// 使线程串行执行,感知上一线程执行的结果,返回当前线程执行的结果。
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);

Async的是可以指定线程池,使用一个新的线程。
不带Async的是使用串行前面那个线程继续执行。

两任务并行执行完成,再执行新任务

CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务1正在执行。。。");
    return 1;
}, executorService);


CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
    System.out.println("任务2正在执行。。。");
    return 2;
}, executorService);

// 两个都执行完后执行。无法获取两个任务的返回值。自己也没有返回值。
future1.runAfterBothAsync(future2 , () -> {
    System.out.println("两个任务都执行完了。。。");
} , executorService);

// 两个任务都执行完之后执行新任务,可以获取到两个任务的返回值,自己没有返回值
future1.thenAcceptBothAsync(future2 , (res1 , res2) -> {
    System.out.println("两个任务都执行完了。。。");
    System.out.println(res1 + ":::::" + res2);
} , executorService);
// 线程并行执行完成,并且执行新任务action,新任务无入参,无返回值
public CompletableFuture<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);

// 线程并行执行完成,并且执行新任务action,新任务有入参,无返回值
public <U> CompletableFuture<Void> thenAcceptBoth(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action);
public <U> CompletableFuture<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, BiConsumer<? super T, ? super U> action, Executor executor);

// 线程并行执行完成,并且执行新任务action,新任务有入参,有返回值
public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletableFuture<V> thenCombineAsync(CompletionStage<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor);

两任务执行完任意一个任务,即可执行新任务。

// 不感知执行完的线程的返回值,自己也不返回任何值。
CompletableFuture<Void> future = future1.runAfterEitherAsync(future2, () -> {
    System.out.println("两个任务重完成了一个任务了,可以执行新任务");
}, executorService);

// 感知执行完的线程的返回值,自己也不返回任何值。
future1.acceptEitherAsync(future2 , (res) -> {
    System.out.println("两线程中的任意一个线程的结果:" + res);
} , executorService);

// 感知执行完的线程的返回值,自己也返回值。
CompletableFuture<String> stringCompletableFuture = future1.applyToEitherAsync(future2, (res) -> {
    return res + "姚云峰";
}, executorService);
System.out.println(stringCompletableFuture.get());
// 任务并行执行,只要其中有一个执行完,就开始执行新任务action,新任务无入参,无返回值
public CompletableFuture<Void> runAfterEither(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action);
public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor);

// 任务并行执行,只要其中有一个执行完,就开始执行新任务action,新任务有入参(入参类型为Object,因为不确定是哪个任务先执行完成),无返回值
public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other, Consumer<? super T> action);
public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action);
public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other, Consumer<? super T> action,Executor executor);

// 任务并行执行,只要其中有一个执行完,就开始执行新任务action,新任务有入参(入参类型为Object,因为不确定是哪个任务先执行完成),有返回值
public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other, Function<? super T, U> fn);
public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn);
public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other, Function<? super T, U> fn,Executor executor);

多任务组合 都完成才返回。完成一个即返回。

// 完成一个即返回。
public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs);
// 两任务完成1任务后即可执行。acceptEitherAsync可以感知之前的结果,自己有返回值。
CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
   System.out.println("查询图片信息。");
   return "Hello.jpg";
});

CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
   System.out.println("查询属性信息。");
   try {
       Thread.sleep(3000);
   } catch (InterruptedException e) {
       throw new RuntimeException(e);
   }
   return "黑色256G";
});

CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
   System.out.println("查询商品介绍信息。");
   return "华为";
});

// 等待这三个都做完。
CompletableFuture<Void> all = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
System.out.println(all.get());
System.out.println("main end");
System.out.println("main end " + futureImg.get() + " " + futureAttr.get() + " " + futureDesc.get());
// 等待三个中的一个完成即可。
CompletableFuture<Object> any = CompletableFuture.anyOf(futureImg, futureAttr, futureDesc);
System.out.println(any.get());
// System.out.println("main end " + futureImg.get() + " " + futureAttr.get() + " " + futureDesc.get());
System.out.println("main end ");

你可能感兴趣的:(后端,java,jvm,开发语言)