并发编程--常用方法以及CompletableFuture

常用方法

  1. 使用:CompletableFuture.supplyAsync方法获取返回值
ExecutorService executor = Executors.newFixedThreadPool(2);
       CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {
    
    
           @Override
           public String get() {
    
    
               try {
    
    
                   Thread.sleep(7000);
               } catch (InterruptedException e) {
    
    
                   e.printStackTrace();
               }
               String s = get4();
               return s;
           }
       }, executor);
       //打印异步结果
       future.thenAccept(e -> System.out.println(e));
  1. ExecutorService方式:execute方法 new Runnable() 这样可以异步的执行Runnable里面的方法。
//声明一个
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
//异步方式一
    @Override
    public void get1() {
    
    
        System.out.println("异步1");
        newCachedThreadPool.execute(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                get4();
            }
        });
    }
  1. 使用注解方式(需要spring扫描)
    3.1 启动类打上@EnableAsync注解开启异步

在这里插入图片描述

 3.2   异步方法加上@Async  标识这是一个异步方法

在这里插入图片描述

 3.3 控制层调用该方法,就会异步执行

在这里插入图片描述

CompletableFuture常用方法

  • CompletableFuture类实现了CompletionStage和Future接口。Future是Java 5添加的类,用来描述一个异步计算的结果,
  • 但是获取一个结果时方法较少,要么通过轮询isDone,确认完成后,调用get()获取值,要么调用get()设置一个超时时间。
  • 但是这个get()方法会阻塞住调用线程,这种阻塞的方式显然和我们的异步编程的初衷相违背。
  • 为了解决这个问题,JDK吸收了guava的设计思想,加入了Future的诸多扩展功能形成了CompletableFuture。
  • /*
    已Async结尾的方法都是可以异步执行的,如果指定了线程池,会在指定的线程池中执行,如果没有指定,默认会在ForkJoinPool.commonPool()中执行。
    关键的入参只有一个Function,它是函数式接口,所以使用Lambda表示.
    /
    /
    *
    • 入参是上一个阶段计算后的结果,返回值是经过转化后结果。
    • public CompletionStage thenApply(Function<? super T,? extends U> fn);
    • public CompletionStage thenApplyAsync(Function<? super T,? extends U> fn);
    • public CompletionStage thenApplyAsync(Function<? super T,? extends U> fn,Executor executor);
      */

    @Test
    public void thenApply() {
    
    
        String result = CompletableFuture.supplyAsync(() -> "hello").thenApply(s -> s + " world").join();
        System.out.println(result);
    }

    @Test
    public void thenApplyAsync() {
    
    
        String result = CompletableFuture.supplyAsync(() -> "hello").thenApplyAsync(s -> s + " world").join();
        System.out.println(result);
    }

    @Test
    public void thenApplyAsyncAndExecutor() {
    
    
        String result = CompletableFuture.supplyAsync(() -> "hello").thenApplyAsync(s -> s + " world", newCachedThreadPool).join();
        System.out.println(result);
    }

/**
* thenAccept是针对结果进行消耗,因为他的入参是Consumer,有入参无返回值。
* public CompletionStage thenAccept(Consumer<? super T> action);
* public CompletionStage thenAcceptAsync(Consumer<? super T> action);
* public CompletionStage thenAcceptAsync(Consumer<? super T> action,Executor executor);
*/

@Test
    public void thenAccept() {
    
    
        CompletableFuture.supplyAsync(() -> "hello").thenAccept(s -> System.out.println(s + " world"));
    }

/**
* 对上一步的计算结果不关心,执行下一个操作。
* public CompletionStage thenRun(Runnable action);
* public CompletionStage thenRunAsync(Runnable action);
* public CompletionStage thenRunAsync(Runnable action,Executor executor);
*/

@Test
public void thenRun() {
    
    
    CompletableFuture.supplyAsync(() -> {
    
    
        int i=1+1;
        try {
    
    
            Thread.sleep(2000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        return "hello";
    }).thenRunAsync(() -> System.out.println("hello world"),newCachedThreadPool);
    while (true) {
    
    
    }
}

@Test
public void thenRunAsync() {
    
    
    CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(2000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        return "hello";
    }).thenRun(() -> System.out.println("hello world"));
    while (true) {
    
    
    }
}

@Test
public void thenRunAsyncAndExecutor() {
    
    
    CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(2000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        return "hello";
    }).thenRunAsync(() -> System.out.println("hello world"), newCachedThreadPool);
    while (true) {
    
    
    }
}

/**
* 结合两个CompletionStage的结果,进行转化后返回
* public <U,V> CompletionStage thenCombine(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn);
* public <U,V> CompletionStage thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn);
* public <U,V> CompletionStage thenCombineAsync(CompletionStage<? extends U> other,BiFunction<? super T,? super U,? extends V> fn,Executor executor);
* 它需要原来的处理返回值,并且other代表的CompletionStage也要返回值之后,利用这两个返回值,进行转换后返回指定类型的值。
*/

  @Test
    public void thenCombine() {
    
    
        String result = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "hello";
        }).thenCombine(CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "world";
        }), (s1, s2) -> s1 + " " + s2).join();
        System.out.println(result);
    }

/**
* 结合两个CompletionStage的结果,进行消耗
* public CompletionStage thenAcceptBoth(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action);
* public CompletionStage thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action);
* public CompletionStage thenAcceptBothAsync(CompletionStage<? extends U> other,BiConsumer<? super T, ? super U> action, Executor executor);
* 它需要原来的处理返回值,并且other代表的CompletionStage也要返回值之后,利用这两个返回值,进行消耗。
*/

  @Test
    public void thenAcceptBoth() {
    
    
        CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "hello";
        }).thenAcceptBoth(CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "world";
        }), (s1, s2) -> System.out.println(s1 + " " + s2));
        while (true) {
    
    
        }
    }

/**
* 在两个CompletionStage都运行完执行。
* public CompletionStage runAfterBoth(CompletionStage<?> other,Runnable action);
* public CompletionStage runAfterBothAsync(CompletionStage<?> other,Runnable action);
* public CompletionStage runAfterBothAsync(CompletionStage<?> other,Runnable action,Executor executor);
* 不关心这两个CompletionStage的结果,只关心这两个CompletionStage执行完毕,之后在进行操作(Runnable)。
*/

 @Test
    public void runAfterBoth() {
    
    
        CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "s1";
        }).runAfterBothAsync(CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "s2";
        }), () -> System.out.println("hello world"));
        while (true) {
    
    
        }
    }

/**
* 两个CompletionStage,谁计算的快,我就用那个CompletionStage的结果进行下一步的转化操作。
* public CompletionStage applyToEither(CompletionStage<? extends T> other,Function<? super T, U> fn);
* public CompletionStage applyToEitherAsync(CompletionStage<? extends T> other,Function<? super T, U> fn);
* public CompletionStage applyToEitherAsync(CompletionStage<? extends T> other,Function<? super T, U> fn,Executor executor);
* 碰到有两种渠道完成同一个事情,所以就可以调用这个方法,找一个最快的结果进行处理。
*/

  @Test
    public void applyToEither() {
    
    
        String result = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "s1";
        }).applyToEither(CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "hello world";
        }), s -> s).join();
        System.out.println(result);
    }

/**
* 两个CompletionStage,任何一个完成了都会执行下一步的操作(Runnable)
* public CompletionStage runAfterEither(CompletionStage<?> other,Runnable action);
* public CompletionStage runAfterEitherAsync(CompletionStage<?> other,Runnable action);
* public CompletionStage runAfterEitherAsync(CompletionStage<?> other,Runnable action,Executor executor);
*/

 @Test
    public void runAfterEither() {
    
    
        CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "s1";
        }).runAfterEither(CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "s2";
        }), () -> System.out.println("hello world"));
        while (true) {
    
    
        }
    }

/**
* 当运行时出现了异常,可以通过exceptionally进行补偿
* public CompletionStage exceptionally(Function<Throwable, ? extends T> fn);
*/

 @Test
    public void exceptionally() {
    
    
        String result = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            if (1 == 1) {
    
    
                throw new RuntimeException("测试一下异常情况");
            }
            return "s1";
        }).exceptionally(e -> {
    
    
            System.out.println(e.getMessage());
            return "hello world";
        }).join();
        System.out.println(result);
    }

/**
* 当运行完成时,对结果的记录。这里的完成时有两种情况,一种是正常执行,返回值。另外一种是遇到异常抛出造成程序的中断。
* 这里为什么要说成记录,因为这几个方法都会返回CompletableFuture,
* 当Action执行完毕后它的结果返回原始的CompletableFuture的计算结果或者返回异常。所以不会对结果产生任何的作用。
* public CompletionStage whenComplete(BiConsumer<? super T, ? super Throwable> action);
* public CompletionStage whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action);
* public CompletionStage whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action,Executor executor);
*/

   @Test
    public void whenComplete() {
    
    
        String result = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            if (1 == 1) {
    
    
                throw new RuntimeException("测试一下异常情况");
            }
            return "s1";
        }).whenComplete((s, t) -> {
            System.out.println(s);
            System.out.println(t.getMessage());
        }).exceptionally(e -> {
    
    
            System.out.println(e.getMessage());
            return "hello world";
        }).join();
        System.out.println(result);
    }

//这里也可以看出,如果使用了exceptionally,就会对最终的结果产生影响,它没有口子返回如果没有异常时的正确的值,这也就引出下面我们要介绍的handle。

/**
 * 运行完成时,对结果的处理。这里的完成时有两种情况,一种是正常执行,返回值。另外一种是遇到异常抛出造成程序的中断。
 * public <U> CompletionStage<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);
 * public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);
 * public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn,Executor executor);
 */
  //出现异常时
    @Test
    public void handleHasException() {
    
    
        String result = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            //出现异常
            if (1 == 1) {
    
    
                throw new RuntimeException("测试一下异常情况");
            }
            return "s1";
        }).handle((s, t) -> {
    
    
            if (t != null) {
    
    
                return "hello world";
            }
            return s;
        }).join();
        System.out.println(result);
    }

    //未出现异常时
    @Test
    public void handle() {
    
    
        String result = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(3000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            return "s1";
        }).handle((s, t) -> {
    
    
            if (t != null) {
    
    
                return "hello world";
            }
            return s;
        }).join();
        System.out.println(result);
    }

    //方法异步执行
    @Test
    public void test2() throws Exception {
    
    
        System.out.println("main函数开始执行");
        ExecutorService executor = Executors.newFixedThreadPool(2);
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
    
    
            @Override
            public Integer get() {
    
    
                System.out.println("===task start===");
                try {
    
    
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
                System.out.println("===task finish===");
                return 3;
            }
        }, executor);
        future.thenAccept(e -> System.out.println(e));
        System.out.println("main函数执行结束");
    }

猜你喜欢

转载自blog.csdn.net/weixin_45528650/article/details/109987332