利用CompletableFuture实现请求合并操作

请求合并的思想:不是每次请求都建立连接,而是把多个请求进行合并,一起访问数据库,节约空间。
所以必然时间会延长,所以请求合并是:时间换空间。
其实其中的想法,都可以想到,唯一想不到的就是CompletableFuture的使用。

原本的Order类

public class Order {
    private String code;
    private String name;
    private String remark;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "Order{" +
                "code='" + code + '\'' +
                ", name='" + name + '\'' +
                ", remark='" + remark + '\'' +
                '}';
    }
}

OrderService类

public class OrderService {

    static Map<String, Order> orderMap = new HashMap<String, Order>();

    static {
        for (int i = 10; i < 10000; i++) {
            Order order = new Order();
            order.setCode("O" + i);
            order.setName("Name" + i);
            order.setRemark(UUID.randomUUID().toString());
            orderMap.put(order.getCode(), order);
        }
        System.out.println("数据初始完");
    }

	//批量请求数据库
    public List<Order> getByCodes(Set<String> codes) {
        try {
            //假装连接数据库
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        List<Order> list = new ArrayList<>();
        for (String code : codes) {
            Order order = orderMap.get(code);
            if (order != null) {
                list.add(order);
            }
        }
        return list;
    }

    public Order getByCode(String code) {
        try {
            //假装连接数据库
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return orderMap.get(code);
    }
}

加入请求合并接口

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.Collectors;

public class MergeService {
    volatile LinkedBlockingQueue<Merge> queue = new LinkedBlockingQueue<>();
    Timer timer = new Timer(true);

    OrderService orderService = new OrderService();

    public MergeService() {
        timer.schedule(new MyTask(), new Date(), 10);
    }

    public Order getByCode(String code) throws ExecutionException, InterruptedException {
        Merge merge = new Merge();
        CompletableFuture<Order> future = new CompletableFuture<Order>();
        merge.setCode(code);
        merge.setFuture(future);
        queue.add(merge);
        return future.get();
    }

	//简略的定时任务
    class MyTask extends TimerTask {

        @Override
        public void run() {
            if (queue.isEmpty()) {
                return;
            }
            Set<String> codes = new HashSet<>(queue.size());
            List<Merge> merges = new ArrayList<>(queue.size());
            while (!queue.isEmpty()) {
                Merge merge = queue.poll();
                codes.add(merge.getCode());
                merges.add(merge);
            }
            List<Order> orders = orderService.getByCodes(codes);
            Map<String, Order> orderMap = orders.stream().collect(Collectors.toMap(Order::getCode, o -> o));
            for (Merge merge : merges) {
                Order order = orderMap.get(merge.getCode());
                merge.getFuture().complete(order);
            }
        }
    }
}

使用到的Merge对象

public class Merge {
    private String code;
    private CompletableFuture<Order> future;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public CompletableFuture<Order> getFuture() {
        return future;
    }

    public void setFuture(CompletableFuture<Order> future) {
        this.future = future;
    }
}

Test类

public class Test {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("开始" + System.currentTimeMillis());
        MergeService mergeService = new MergeService();
        OrderService orderService = new OrderService();
        int num = 500;
        CountDownLatch countDownLatch = new CountDownLatch(num);
        for (int i = 0; i < num; i++) {
            String code = "O" + i;
            new Thread(() -> {
                countDownLatch.countDown();
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("组队完成" + System.currentTimeMillis());
                try {
                    System.out.println(Thread.currentThread().toString() + mergeService.getByCode(code) + System.currentTimeMillis());
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //System.out.println(Thread.currentThread().toString() + orderService.getByCode(code) + System.currentTimeMillis());
            }).start();
        }
    }
}
发布了148 篇原创文章 · 获赞 18 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_33321609/article/details/104508387