• Java线程池-异步任务编排


    1.初始化线程的4 种方式

    1.继承 Thread

    package com.atguigu.gulimall.mytest;
    import org.junit.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    public class MytestApplicationTests {
    
    
        @Test
        public void test() {
    
            Thread1 thread1 = new Thread1();
            thread1.run();
        }
    
        /**
         * 继承Thread接口
         */
        public class Thread1 extends Thread{
    
            @Override
            public void run() {
                System.out.println("thread1运行开始");
                try {
                    Thread.sleep(5000);//单位毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("thread1运行结束");
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述

    2.实现 Runnable 接口

    package com.atguigu.gulimall.mytest;
    import org.junit.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    public class MytestApplicationTests {
    
        @Test
        public void test() {
    
            Thread2 thread2 = new Thread2();
            thread2.run();
        }
        
    
        /**
         * 实现Runnable接口
         */
        public class Thread2 implements Runnable{
    
            @Override
            public void run() {
                System.out.println("thread2运行开始");
                try {
                    Thread.sleep(5000);//单位毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("thread2运行结束");
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    在这里插入图片描述

    3.实现 Callable 接口

    FutureTask可以拿到返回结果,可以处理异常
    futureTask.get()阻塞等待整个线程执行完成,获取返回结果

    package com.atguigu.gulimall.mytest;
    import org.junit.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    
    @SpringBootTest
    public class MytestApplicationTests {
    
        @Test
        public void test() throws ExecutionException, InterruptedException {
    
            Callable01 callable01 = new Callable01();
            FutureTask<Integer> futureTask = new FutureTask<>(callable01);
    
            Thread thread = new Thread(futureTask);
            thread.start(); //启动线程
            Integer integer = futureTask.get();//等待线程返回结果之前, 下面的代码不会执行
            System.out.println(integer);
            System.out.println("任务完成");
        }
    
    
    
        /**
         *  实现Callable接口
         */
        public class Callable01 implements Callable<Integer> {
    
            @Override
            public Integer call() throws Exception {
                System.out.println("thread3运行开始");
                try {
                    Thread.sleep(5000);//单位毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("thread3运行结束");
                return 10;
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    在这里插入图片描述

    4.线程池ExecutorService

    package com.atguigu.gulimall.mytest;
    import org.junit.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.util.concurrent.*;
    
    @SpringBootTest
    public class MytestApplicationTests {
    
        @Test
        public void test() throws ExecutionException, InterruptedException {
            Callable01 callable01 = new Callable01();
    
            ExecutorService executorService = Executors.newFixedThreadPool(10);
            FutureTask<Integer> futureTask = (FutureTask<Integer>)executorService.submit(callable01);
            System.out.println("等待结果");
            System.out.println(futureTask.get());
            System.out.println("任务完成");
        }
    
    
        /**
         *  实现Callable接口
         */
        public class Callable01 implements Callable<Integer> {
    
            @Override
            public Integer call() throws Exception {
                System.out.println("thread3运行开始");
                try {
                    Thread.sleep(5000);//单位毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("thread3运行结束");
                return 10;
            }
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述

    2.线程池的7大参数

    线程池工作流程图
    在这里插入图片描述

    在这里插入图片描述

    • corePoolSize(必需):核心线程数。默认情况下,核心线程会一直存活,但是当将
      allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。

    • maximumPoolSize(必需):线程池所能容纳的最大线程数。当活跃线程数达到该数值后,后续的新任务将会阻塞。

    • keepAliveTime(必需):线程闲置超时时长。如果超过该时长,非核心线程就会被回收。如果将 allowCoreThreadTimeout 设置为 true 时,核心线程也会超时回收。

    • unit(必需):指定 keepAliveTime参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。

    • workQueue(必需):任务队列。通过线程池的 execute() 方法提交的 Runnable对象将存储在该参数中。其采用阻塞队列实现。

    • threadFactory(可选):线程工厂。用于指定为线程池创建新线程的方式。

    • handler(可选):拒绝策略。当达到最大线程数时需要执行的饱和策略。

    一个线程池 core 7; max 20 ,queue:50,100 并发进来怎么分配的?
    先有 7 个能直接得到执行,接下来 50 个进入队列排队,在多开 13 个继续执行。现在 70 个 被安排上了。剩下 30 个默认拒绝策略。

    3.常见的4 种线程池

    • newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若 无可回收,则新建线程。

    • newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

    • newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

    • newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行

    4.CompletableFuture 异步编排

    1.创建异步对象

    CompletableFuture 提供了四个静态方法来创建一个异步操作。
    在这里插入图片描述
    1、runAsync都是没有返回结果的,supplyAsync都是可以获取返回结果的
    2、可以传入自定义的线程池,否则就用默认的线程池;

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //异步任务1
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                System.out.println("当前线程1:" + Thread.currentThread().getId());
                int i = 10 / 2;
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("运行结果1:" + i);
            }, executor);
    
            //异步任务2
            CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
                System.out.println("当前线程2:" + Thread.currentThread().getId());
                int i = 10 / 2;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("运行结果2:" + i);
                return i;
            }, executor);
    
            Integer res2 = (Integer) future2.get();
            System.out.println("res2="+res2);
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    在这里插入图片描述

    2.计算完成时回调方法

    在这里插入图片描述

    • whenComplete 可以处理正常和异常的计算结果,exceptionally 处理异常情况。
    • whenComplete 和 whenCompleteAsync 的区别:
      whenComplete:是执行当前任务的线程执行继续执行whenComplete 的任务。 whenCompleteAsync:是执行把 whenCompleteAsync这个任务继续提交给线程池 来进行执行。
    • 方法不以 Async 结尾,意味着 Action 使用相同的线程执行,而 Async 可能会使用其他线程
      执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)

    1.在 supplyAsync、runAsync执行完毕后还想做其他任务就可以使用链式调用whenComplete(是指当前任务的线程执行继续执行)、whenCompleteAsync(是重新提交到线程池进行执行),这两个可以接收到成功值或者异常信息,只能作为监听成功或失败。

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                return "ok";
            }, executor).whenComplete((res,exception)->{
                System.out.println("结果是:"+res+"异常是:"+exception);
            });
            String res = future.get();
            System.out.println("线程返回结果:"+res);
    
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述
    2.还可以链式调用exceptionally,可以获取到异常信息并且可以修改最终值.

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                int i = 10/0; //模拟异常
                return "ok";
            }, executor).whenComplete((res,exception)->{
                System.out.println("结果是:"+res+"异常是:"+exception);
            }).exceptionally((exception)->{
                return "not ok";
            });
            String res = future.get();
            System.out.println("线程返回结果:"+res);
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    3.handle 方法

    handle方法可以接受两个参数(成功值,异常信息),返回一个参数(可以修改最终返回值),相当于方法执行后的处理

    package com.atguigu.gulimall.mytest.test;
    
    import io.swagger.models.auth.In;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                //int i = 10/0; //模拟异常
                return "ok";
            }, executor).handle((res, exception) -> {
                if (exception==null){
                    System.out.println("结果是:" + res);
                    return res;
                }else{
                    System.out.println("异常是:" + exception);
                    return "not ok";
                }
            });
    
            String res = future.get();
            System.out.println("线程返回结果:"+res);
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述

    5.线程串行化方法

    在这里插入图片描述
    提示: 链式调用方法后不加Async是指当前任务的线程执行继续执行,加上Async是重新提交到线程池进行执行

    1.thenRun、thenRunAsync

    要上面的任务执行完毕后才开始执行此方法的后续操作,无返回结果。

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture future = CompletableFuture.supplyAsync(() -> {
                System.out.println("one");
                return "ok";
            },executor).thenRunAsync(()->{
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("执行后续操作。。。");
            },executor);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    2.thenAccept、thenAcceptAsync

    有一个入参(消费处理结果),接收处理结果进行后续操作,无返回结果。

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture future = CompletableFuture.supplyAsync(() -> {
                System.out.println("one");
                return "ok";
            }, executor).thenAcceptAsync((res)->{
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("接收到结果:"+res+"执行后续操作。。。");
            },executor);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    3.thenApply、thenApplyAsync

    接收返回结果,并进行后续操作,并返回当前任务的返回值

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                return "ok";
            }, executor).thenApplyAsync((res)->{
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("接收到结果:"+res+"执行后续操作。。。");
                return "ok666";
            },executor);
    
            String res = future.get();
            System.out.println("线程返回结果:"+res);
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    4.两任务组合 - 都要完成

    在这里插入图片描述

    两个任务必须都完成,触发该任务。

    1.thenCombine、thenCombineAsync:组合两个futre的返回结果,并且返回当前任务的返回值

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<Integer> supplyAsync1 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务1执行完毕");
                return 10;
            }, executor);
            CompletableFuture<Integer> supplyAsync2 = CompletableFuture.supplyAsync(() -> {
                System.out.println("任务2执行完毕");
                return 20;
            }, executor);
            CompletableFuture<Integer> combineAsync = supplyAsync1.thenCombineAsync(supplyAsync2, (res1, res2) -> {
                System.out.println("结合任务1和任务2的结果计算出任务3,并返回");
                return res1+res2;
            }, executor);
            Integer res = combineAsync.get();
            System.out.println("结果:"+res);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述

    2.thenAcceptBoth、thenAcceptBothAsync:组合两个 future,获取两个 future 任务的返回结果,然后处理任务,没有返回值。

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<Integer> supplyAsync1 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务1执行完毕");
                return 10;
            }, executor);
            CompletableFuture<Integer> supplyAsync2 = CompletableFuture.supplyAsync(() -> {
                System.out.println("任务2执行完毕");
                return 20;
            }, executor);
            CompletableFuture<Void> acceptBothAsync = supplyAsync1.thenAcceptBothAsync(supplyAsync2, (res1, res2) -> {
                System.out.println("结合任务1和任务2的结果执行任务3,没有返回值!");
                System.out.println("res1+res2="+(res1+res2));
            }, executor);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    3.runAfterBoth、thenAfterBothAsync:组合两个futre,不需要返回结果,只需要处理两个Future后执行该任务。

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<Integer> supplyAsync1 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务1执行完毕");
                return 10;
            }, executor);
            CompletableFuture<Integer> supplyAsync2 = CompletableFuture.supplyAsync(() -> {
                System.out.println("任务2执行完毕");
                return 20;
            }, executor);
    
            CompletableFuture<Void> afterBothAsync = supplyAsync1.runAfterBothAsync(supplyAsync2, () -> {
                System.out.println("任务1和任务2执行完执行任务3.没有返回值!");
            }, executor);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    5.两任务组合 - 一个完成

    在这里插入图片描述
    1.applyToEitherAsync、applyToEither: 两个任务有一个执行完成,获取它的返回值,处理任务并有新的返回值。

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<Integer> supplyAsync1 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务1执行完毕");
                return 10;
            }, executor);
            CompletableFuture<Integer> supplyAsync2 = CompletableFuture.supplyAsync(() -> {
                System.out.println("任务2执行完毕");
                return 20;
            }, executor);
    
            supplyAsync1.applyToEitherAsync(supplyAsync2,(res)->{
                System.out.println("res="+res);
                System.out.println("只要有一个完成就接收值,处理并返回值!");
                return 3;
            },executor);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    在这里插入图片描述
    2.acceptEitherAsync、acceptEither:两个任务有一个执行完成,获取它的返回值,处理任务,没有新的返回值。

    supplyAsync1.acceptEitherAsync(supplyAsync2,(res)->{
                System.out.println("只要有一个完成就接收值,处理不能返回值!");
            },executor);
    
    • 1
    • 2
    • 3

    3.runAfterEitherAsync、runAfterEither:两个任务有一个执行完成,不需要获取 future 的结果,处理任务,也没有返回值。

    supplyAsync1.runAfterEitherAsync(supplyAsync2,()->{
                System.out.println("只要有一个完成不接受值,处直接理不能返回值!");
            },executor);
    
    • 1
    • 2
    • 3

    6.多任务组合

    在这里插入图片描述

    1.allOf:等待所有任务完成,没有返回值

    package com.atguigu.gulimall.mytest.test;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<Integer> supplyAsync1 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务1执行完毕");
                return 10;
            }, executor);
            CompletableFuture<Integer> supplyAsync2 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(6000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务2执行完毕");
                return 20;
            }, executor);
    
            CompletableFuture<Integer> supplyAsync3 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务3执行完毕");
                return 30;
            }, executor);
    
            CompletableFuture<Void> all = CompletableFuture.allOf(supplyAsync1, supplyAsync2, supplyAsync3);
            System.out.println("ok1");
            all.get(); //阻塞,等待所有任务完成才执行后续代码
            System.out.println("ok2");
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    在这里插入图片描述

    2.anyOf:只要有一个任务完成, 可以有返回值

    package com.atguigu.gulimall.mytest.test;
    
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class threadTest {
    
        public static ExecutorService executor = Executors.newFixedThreadPool(10);
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
    
            CompletableFuture<Integer> supplyAsync1 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务1执行完毕");
                return 10;
            }, executor);
            CompletableFuture<Integer> supplyAsync2 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(6000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务2执行完毕");
                return 20;
            }, executor);
    
            CompletableFuture<Integer> supplyAsync3 = CompletableFuture.supplyAsync(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("任务3执行完毕");
                return 30;
            }, executor);
    
            CompletableFuture<Object> all = CompletableFuture.anyOf(supplyAsync1, supplyAsync2, supplyAsync3);
            System.out.println("ok1");
            Integer res = (Integer) all.get(); //阻塞,等待有一个任务完成才执行后续代码
            System.out.println("res="+res);
            System.out.println("ok2");
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    在这里插入图片描述

  • 相关阅读:
    多表查询(连接查询)
    .net lambda表达式合并
    LabVIEW面向对象-面向对象
    [附源码]Java计算机毕业设计SSM飞羽羽毛球馆管理系统
    在Unity中制作完整的技能系统(代码篇)
    信息系统项目管理师-采购管理论文提纲
    QListWidget 插入QListWidgetItem 需要避开的坑
    webpack配置全局scss
    电脑入门:路由器常见问题排错步骤
    C++_模板函数重载
  • 原文地址:https://blog.csdn.net/qq_41865229/article/details/126346335