JDK8-11-CompletableFuture(4)- supplyAsync 方法使用

JDK8-11-CompletableFuture(4)- supplyAsync 方法使用

生活中有一些多线程的例子,例如顾客去餐馆点餐,大致可以分为如下几个步骤:
1.顾客进入餐厅
2.顾客开始点餐
3.厨师按照顾客所选菜品开始炒菜
4.厨师打饭(假设没有服务员)
5.顾客开始吃饭
其中,在厨师准备饭菜的3,4步骤中,顾客处于等待状态,可以做些其他事情,比如玩手机,下面用程序模拟这个案例:

工具类,用于模拟耗时和打印当前时间戳和线程信息

import java.util.StringJoiner;

public class PrintTool {

    public static void sleep(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void printTimeAndThread(String str) {
        String result = new StringJoiner("\t|\t")
                .add(String.valueOf(System.currentTimeMillis()))
                .add(String.valueOf(Thread.currentThread().getId()))
                .add(Thread.currentThread().getName())
                .add(str)
                .toString();
        System.out.println(result);
    }
}

使用 supplyAsync 开启异步任务的例子:

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class SupplyAsyncTest01 {

    public static void main(String[] args) {
        PrintTool.printTimeAndThread("顾客进入餐厅。。。");
        PrintTool.printTimeAndThread("顾客开始点餐。。。");
        CompletableFuture<String> cf = CompletableFuture.supplyAsync(()->{
            PrintTool.printTimeAndThread("厨师开始炒菜。。。");
            PrintTool.sleep(500);
            PrintTool.printTimeAndThread("厨师开始打饭。。。");
            PrintTool.sleep(200);
            return "番茄炒蛋+米饭";
        });
        PrintTool.printTimeAndThread("顾客玩手机中。。。");
        try {
            PrintTool.printTimeAndThread(String.format("顾客开始吃%s",cf.get()));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

程序执行结果:

1665891657796	|	1	|	main	|	顾客进入餐厅。。。
1665891657798	|	1	|	main	|	顾客开始点餐。。。
1665891660537	|	1	|	main	|	顾客玩手机中。。。
1665891660537	|	14	|	ForkJoinPool.commonPool-worker-1	|	厨师开始炒菜。。。
1665891661044	|	14	|	ForkJoinPool.commonPool-worker-1	|	厨师开始打饭。。。
1665891661274	|	1	|	main	|	顾客开始吃番茄炒蛋+米饭

从执行结果中可以看出,main线程处理顾客相关动作,ForkJoinPool.commonPool-worker-1 线程处理厨师相关动作,从时间戳可以看出顾客玩手机和厨师开始炒菜都是1665891660537 ,符合异步处理场景

分析

supplyAsync 是 CompletableFuture 类静态方法,包括有无线程池入参两个重载方法

public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
    return asyncSupplyStage(asyncPool, supplier);
}
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,
                                                       Executor executor) {
   return asyncSupplyStage(screenExecutor(executor), supplier);
}

其中入参 Supplier(翻译为:供应商) 为 函数式接口(有且仅有一个抽象方法)

@FunctionalInterface
public interface Supplier<T> {

    /**
     * Gets a result.
     *
     * @return a result
     */
    T get();
}

如果不传入Executor 入参则默认使用 ForkJoinPool 线程池创建异步任务

本例参考:https://www.bilibili.com/video/BV1nA411g7d2/?spm_id_from=333.337.search-card.all.click&vd_source=b268fbae30d6377c5ccc3cb09f68822e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值