Java多线程学习笔记(二)

一、Future接口

java.util.concurrent包下,有以下方法:

  • cancel(boolean var1):取消Callable任务,未开始或已完成返回false,boolean参数表示是否中断执行中的Callable任务
  • isCanceled():判断Callable任务是否取消了
  • isDone():判断是否完成
  • get():获得Callable的返回值
  • get(long time, TimeUnit unit):设置超时时间,防止无限时间的等待

二、CompletionStage接口

java.util.concurrent包下,jdk1.8才引入。用于阶段处理,实现链式的阶段型的操作,使线程与线程之间可以愉快的进行对话。目前只有CompletableFuture一个实现类。

1、串行执行,方法前缀then和runAfterBoth方法

后缀带Async,可以用线程池异步处理,默认线程池ForkJoinPool,3个一组,共27个方法:
在这里插入图片描述

1)、thenRun方法,前一阶段结果不影响,无返回

public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
    System.out.println("main线程start");
    CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("线程名称:" + Thread.currentThread().getName());
        return 1;
    }).thenRunAsync(() -> {
    
    
        System.out.println("线程名称:" + Thread.currentThread().getName());
    }, EXECUTOR_SERVICE);

    future.get();
    System.out.println("main线程end");
}

输出结果:
在这里插入图片描述

2)、thenAccept方法,前一阶段结果变入参,无返回

public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
    System.out.println("main线程start");
    CompletableFuture<Void> future = CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("线程名称:" + Thread.currentThread().getName());
        return 1;
    }).thenAccept((t) -> {
    
    
        System.out.println("线程名称:" + Thread.currentThread().getName());
        System.out.println(t);
    });

    future.get();
    System.out.println("main线程end");
}

输出结果:
在这里插入图片描述

3)、thenApply方法,前一阶段结果变入参,有返回

public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
    System.out.println("main线程start");
    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("线程名称:" + Thread.currentThread().getName());
        return 1;
    }).thenApply((t) -> {
    
    
        System.out.println("线程名称:" + Thread.currentThread().getName());
        System.out.println(t);
        return t;
    });

    Integer t = future.get();
    System.out.println("返回结果:" + t);
    System.out.println("main线程end");
}

输出结果:
在这里插入图片描述

4)、thenCombine方法,前一阶段 f1 和 f2 的结果变入参,有返回

public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
        System.out.println("main线程start");

        CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(2000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("f1线程名称:" + Thread.currentThread().getName());
            return 1;
        });

        CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("f2线程名称:" + Thread.currentThread().getName());
            return 2;
        }).thenCombine(f1, (t, u) -> {
    
    
            System.out.println("结合后线程名称:" + Thread.currentThread().getName());
            System.out.println("t:" + t);
            System.out.println("u:" + u);
            return t + u;
        });

        Integer result = f2.get();
        System.out.println("返回结果:" + result);
        System.out.println("main线程end");
    }

输出结果:
在这里插入图片描述

5)、thenAcceptBoth方法(和thenCombine方法一样,只是无返回)

6)、runAfterBoth方法(和thenCombine方法一样,只是无返回、无入参)

7)、thenCompose方法(和thenApply方法一样,只是传入函数的返回是CompletableFuture<>)

8)、whenComplete方法,入参多了一个异常,无返回值

public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
    System.out.println("main线程start");
    CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(2000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("f1线程名称:" + Thread.currentThread().getName());
//            return 1;
        throw new RuntimeException("异常了!");
    }).whenComplete((t, u) -> {
    
    
        System.out.println("f2线程名称:" + Thread.currentThread().getName());
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        if (u != null) {
    
    
            System.out.println("异常1");
            u.printStackTrace();
        } else {
    
    
            System.out.println("接收到结果:" + t);
        }
    }).thenCompose((t) -> {
    
    
        System.out.println("thenCompose线程名称:" + Thread.currentThread().getName());
        System.out.println(t);
        return CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(4000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("f3线程名称:" + Thread.currentThread().getName());
            return 2;
        });
    }).exceptionally((t) -> {
    
    
        System.out.println("f4线程名称:" + Thread.currentThread().getName());
        try {
    
    
            Thread.sleep(3000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("异常2");
        t.printStackTrace();
        return 3;
    });
    Integer result = f1.get();
    System.out.println("返回结果:" + result);
    System.out.println("main线程end");
}

输出结果:
在这里插入图片描述

9)、handle方法,和whenComplete方法一样,多了返回值

2、前一阶段的两个任务中,只需完成一个就执行后面的

在这里插入图片描述

1)、applyToEither方法,只需要前一阶段其中一个任务执行完,就会执行,并将其结果作为入参,有返回值

public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
    System.out.println("main线程start");
    CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(2000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("f1线程名称:" + Thread.currentThread().getName());
        return 1;
    });
    CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("f2线程名称:" + Thread.currentThread().getName());
        return 2;
    }).applyToEither(f1, (t) -> {
    
    
        System.out.println("结合后线程名称:" + Thread.currentThread().getName());
        System.out.println("t:" + t);
        return t;
    });
    Integer result = f2.get();
    System.out.println("返回结果:" + result);
    System.out.println("main线程end");
}

输出结果:
在这里插入图片描述

2)、acceptEither方法(和applyToEither方法一样,只是无返回)

3)、runAfterEither方法(和applyToEither方法一样,只是无返回、无入参)

3、异常处理

1)、exceptionally方法,捕获异常

public static void main(String[] args) throws ExecutionException, InterruptedException {
    
    
    System.out.println("main线程start");
    CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {
    
    
        try {
    
    
            Thread.sleep(2000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        System.out.println("f1线程名称:" + Thread.currentThread().getName());
        throw new RuntimeException("异常了!");
    }).thenCompose((t) -> {
    
    
        System.out.println("thenCompose线程名称:" + Thread.currentThread().getName());
        System.out.println(t);
        return CompletableFuture.supplyAsync(() -> {
    
    
            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            System.out.println("f2线程名称:" + Thread.currentThread().getName());
            return 2;
        });
    }).exceptionally((t) -> {
    
    
        System.out.println("f3线程名称:" + Thread.currentThread().getName());
        try {
    
    
            Thread.sleep(3000);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
        t.printStackTrace();
        return 3;
    });
    Integer result = f1.get();
    System.out.println("返回结果:" + result);
    System.out.println("main线程end");
}

输出结果:
在这里插入图片描述

三、多线程学习笔记

Java多线程学习笔记(一)

猜你喜欢

转载自blog.csdn.net/qq_36514197/article/details/123135140