一.场景

       今天看到一个需求:收到客户端的订单请求以后,需要检查商品的库存能否满足,并且查询该客户按照当前的价格策略能否享受订单的折扣才能接受该订单,而这两个查询是非常耗时的操作。

二.分析

1.按照最初的单线程的方式实现如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AsynchronousTest {
    int count=20;//库存量
    int sumPare=100;//要求达到的订单价格
    private ExecutorService executorService= Executors.newCachedThreadPool();//创建线程池

    //单线程,进行订单处理流程
    public void getOrder(String orderName,int parce){
        System.out.println("获取到订单信息"+orderName);
        //判断库存的充足情况
        boolean kucun=count<=0?true:false;
        //判断是否能够进行订单折扣
        boolean flag=parce>=sumPare?true:false;
        //进行下单
        if(kucun && flag){
            System.out.println("下单成功,订单名:"+orderName+"订单价格:"+parce);
        }else{
            System.out.println("下单失败"+orderName);
        }
    }
}

2.分析:根据需求两个查询的操作会非常耗时,因此我们可以进行优化,两个查询任务采用异步形式实现,具体代码如下:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

public class DemoAsynchronous {

    public static void main(String[] args) throws Exception{
        //创建两个线程
        ExecutorService executor=Executors.newFixedThreadPool(2);
        //任务一:查看库存是否充足
        CompletableFuture future1 = CompletableFuture.supplyAsync(()-> {
            try {
                System.out.println("任务一:查询库存状态,大概需要8秒...");
                //省略业务判断方法.......
                Thread.sleep(8000);
                System.out.println("任务一:库存查询结束...");
                return true;
            } catch (InterruptedException e) {
                System.err.println("查询出错");
                return false;
            }
        },executor);

        //任务二:查询价格是否符合下单
        CompletableFuture future2=CompletableFuture.supplyAsync(()->{
            try {
                System.out.println("任务二:查询订单价格是否符合要求,大概需要5秒...");
                //省略业务判断价格是否符合下单.......
                Thread.sleep(5000);
                System.out.println("任务二:订单价格查询结束...");
                return true;
            } catch (InterruptedException e) {
                System.err.println("查询出错");
                return false;
            }
        },executor);

        future1.thenAccept((e)->{System.out.println("任务一:查询结果是:"+(boolean)e);});
        future2.thenAccept((e)->{System.out.println("任务二:查询结果是:"+(boolean)e);});
        System.out.println("等待查询结果中");
        boolean one= (boolean) future1.get();
        boolean two= (boolean) future1.get();

        if( one && two ){
            System.out.println("下单成功!");
        }else{
            System.out.println("下单失败!");
        }

    }
}

执行结果是:

任务一:查询库存状态,大概需要8秒...
任务二:查询订单价格是否符合要求,大概需要5秒...
等待查询结果中
任务二:订单价格查询结束...
任务二:查询结果是:true
任务一:库存查询结束...
任务一:查询结果是:true
下单成功!

三.总结

1.异步方式实现的代码中,我们创建了两个线程,启动两个线程执行: 任务一:库存查询任务二:订单价格是否满足下单要求;这两个线程的执行不会阻塞主,线程主线程main会继续执行。

2.后期又计算了两种方式的执行速度,单线程执行13s,异步执行8s,之后又把两个任务的睡眠时间进行调整更大值,发现两种方式的时间差距逐渐拉大,总结:异步方式在耗时操作时能够得到很好的优化。