• 将一个简单远程调用的方式例子改为异步调用


    将一个简单远程调用的方式例子改为异步调用

    package com.xsxy.asynctest.test03;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.TimeUnit;
    import java.util.stream.Collectors;
    
    /**
     * 将一个简单远程调用的方式例子改为异步调用
     */
    public class Test04CompletableFuturePractice {
    
        public static void main(String[] args) {
            List<String> ipList = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                ipList.add("192.168.0." + i);
            }
            syncMethod(ipList);
            AsyncMethod(ipList);
        }
    
        /**
         * 同步顺序调用耗时 time:10138
         *
         * @param ipList
         */
        public static void syncMethod(List<String> ipList) {
            long start = System.currentTimeMillis();
            ipList.forEach(ip -> {
                rpcCall(ip, 8080);
            });
            System.out.println("time:" + (System.currentTimeMillis() - start));
        }
    
        /**
         * 异步调用耗时 time:4029
         *
         * @param ipList
         */
        public static void AsyncMethod(List<String> ipList) {
            long start = System.currentTimeMillis();
            // 同步调用转异步
            List<CompletableFuture<String>> completableFutureList = ipList.stream().map(ip -> CompletableFuture.supplyAsync(() -> rpcCall(ip, 9090)))
                    .collect(Collectors.toList());
    
            // 阻塞等待所有调用都结束
            List<String> resList = completableFutureList.stream().map(CompletableFuture::join).collect(Collectors.toList());
            // resList.forEach(System.out::println);
    
            System.out.println("time:" + (System.currentTimeMillis() - start));
        }
    
    
        public static String rpcCall(String ip, int port) {
            System.out.println("rpcCall=ip:" + ip + ",port:" + port);
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
    
            }
            return "res" + port;
        }
    }
    
    

    其他completableFuture的使用例子

    package com.xsxy.asynctest.test03;
    
    import java.util.concurrent.*;
    import java.util.function.Consumer;
    import java.util.function.Supplier;
    
    public class Test01CompletableFutureSet {
        public static final int AVALIABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
        public static ThreadPoolExecutor executor = new ThreadPoolExecutor(AVALIABLE_PROCESSORS, AVALIABLE_PROCESSORS, 1, TimeUnit.MINUTES,
                new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.CallerRunsPolicy());
    
    
        public static void main(String[] args) throws Exception {
            // waitNotify();
            // runAsync();
            // runAsync1WithBizExecutor();
            // supplyAsync();
            // thenRun();
            thenAccept();
        }
    
        /**
         * 这里使用CompletableFuture实现了 通知等待模型,主线程调用future的get()方法等待future返回结果,一开始由于future结果没有设置,
         * 所以主线程被阻塞挂起,等异步任务休眠3s,然后调用future的complete方法模拟主线程等待的条件完成,这时候主线程就会从get()方法返回。
         */
        public static void waitNotify() throws ExecutionException, InterruptedException, TimeoutException {
            CompletableFuture completableFuture = new CompletableFuture();
            executor.execute(() -> {
                System.out.println("executor sleep 3 seconds");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (Exception e) {
    
                }
    
                completableFuture.complete("executor done");
            });
    
            System.out.println("main wait completableFurture result");
            // 阻塞获取completableFuture结果
            System.out.println(completableFuture.get());
            // 设置超时时间,超时时会保timeoutException异常
            // System.out.println(completableFuture.get(1, TimeUnit.SECONDS));
            System.out.println("main end");
        }
    
        /**
         * 实现无返回值的异步计算:当你想异步执行一个任务,并且不需要任务的执行结果时可以使用该方法,比如异步打日志,异步做消息通知等
         * 在默认情况下,runAsync(Runnablerunnable)方法是使用整个JVM内唯一的ForkJoinPool.commonPool()线程池来执行异步任务的,
         * 使用runAsync (Runnable runnable, Executor executor)
         */
        public static void runAsync() throws Exception {
            CompletableFuture future = CompletableFuture.runAsync(() -> {
                System.out.println("execute completableFuture task");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (Exception e) {
    
                }
            });
    
            System.out.println("mian");
            // 无返回值
            System.out.println(future.get());
            System.out.println("main end");
        }
    
        /**
         * 使用自定义线程池 实现无返回值的异步计算
         */
        public static void runAsync1WithBizExecutor() throws Exception {
            // 使用自定义的线程池
            CompletableFuture future = CompletableFuture.runAsync(() -> {
                System.out.println("run completableFuture task");
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (Exception e) {
    
                }
            }, executor);
    
            System.out.println("main");
            System.out.println(future.get());
            System.out.println("main end");
        }
    
        /**
         * 实现有返回值的异步计算
         * 在默认情况下,supplyAsync(Supplier<U> supplier)方法是使用整个JVM内唯一的ForkJoinPool.commonPool()线程池来执行异步任务的,
         * 使用supply-Async(Supplier<U> supplier,Executor executor)方法允许我们使用自己制定的线程池来执行异步任务
         */
        public static void supplyAsync() throws Exception {
            CompletableFuture future = CompletableFuture.supplyAsync(new Supplier<Object>() {
                @Override
                public Object get() {
                    System.out.println("completableFuture supplyAsync run");
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (Exception e) {
    
                    }
                    // 返回异步计算结果
                    return "supplyAsync return";
                }
            });
    
            System.out.println("main");
            System.out.println(future.get());
            System.out.println("main end");
        }
    
        /**
         * 基于thenRun实现异步任务,执行完毕后,激活异步任务B执行,需要注意的是,这种方式激活的异步任务B是拿不到任务A的执行结果的
         */
        public static void thenRun() throws ExecutionException, InterruptedException {
            CompletableFuture future = CompletableFuture.supplyAsync(new Supplier<String>() {
                @Override
                public String get() {
                    System.out.println("completableFuture run");
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (Exception e) {
    
                    }
                    return "completableFuture supplyAsync return";
                }
            });
    
            CompletableFuture futuretwo = future.thenRun(() -> {
                System.out.println("thenRun  --");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (Exception e) {
    
                }
            });
    
            System.out.println("main");
            System.out.println(futuretwo.get());
            System.out.println("main end");
        }
    
        /**
         * 基于thenAccept实现异步任务,执行完毕后,激活异步任务B执行,需要注意的是,这种方式激活的异步任务B是可以拿到任务A的执行结果的
         */
        public static void thenAccept() throws ExecutionException, InterruptedException {
            CompletableFuture future = CompletableFuture.supplyAsync(new Supplier<String>() {
                @Override
                public String get() {
                    System.out.println("completableFuture run");
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (Exception e) {
    
                    }
                    return "completableFuture supplyAsync return";
                }
            });
    
            CompletableFuture futuretwo = future.thenAccept(new Consumer<String>() {
                @Override
                public void accept(String o) {
                    System.out.println(o);
                }
            });
    
            System.out.println("main");
            System.out.println(futuretwo.get());
            System.out.println("main end");
        }
    }
    

    package com.xsxy.asynctest.test03;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    import java.util.function.Supplier;
    
    
    public class Test02TwoCompletableFuture {
    
    
        /**
         * CompletableFuture功能强大的原因之一是其可以让两个或者多个Completable-Future进行运算来产生结果
         * <p>
         * main函数中首先调用方法doSomethingOne("123")开启了一个异步任务,并返回了对应的CompletableFuture对象,
         * 我们取名为future1,然后在future1的基础上调用了thenCompose方法,企图让future1执行完毕后,激活使用其结果作
         * 为doSomethingTwo(String companyId)方法的参数的任务
         */
        public static void main(String[] args) throws Exception {
            // 串行
            // testThenCompose();
            // 并行计算
            // testThencombine();
            // 批量
            testAllOf();
    
        }
    
        /**
         * 基于thenCompose实现当一个CompletableFuture执行完毕后,执行另外一个CompletableFuture
         */
        public static void testThenCompose() throws Exception {
            CompletableFuture<String> future = doSomething1("123").thenCompose(id -> doSomething2(id));
            // CompletableFuture<String> future = doSomething1("123").thenCompose(Test02TwoCompletableFuture::doSomething2);
            System.out.println("main");
            System.out.println(future.get());
            System.out.println("main end");
        }
    
        /**
         * 基于thenCombine实现当一个CompletableFuture执行完毕后,执行另外一个CompletableFuture
         */
        public static void testThencombine() throws Exception {
            // CompletableFuture<String> future = doSomething1("123").thenCombine(doSomething2("456"), (str1, str2) -> str1 + ":" + str2);
            CompletableFuture<String> future = doSomething1("123").thenCombine(doSomething2("456"), (str1, str2) -> {
                return str1 + ":" + str2;
            });
            System.out.println("main");
            System.out.println(future.get());
            System.out.println("main end");
        }
    
        /**
         * 基于allOf等待多个并发运行的CompletableFuture任务执行完毕
         *
         * 调用了四次doSomethingOne方法,分别返回一个CompletableFuture对象,然后收集这些CompletableFuture到futureList列表。
         * 调用allOf方法把多个CompletableFuture转换为一个result,代码3在result上调用get()方法会阻塞调用线程,
         * 直到futureList列表中所有任务执行完毕才返回
         */
        public static void testAllOf() throws ExecutionException, InterruptedException {
            List<CompletableFuture<String>> futureList = new ArrayList<>();
            futureList.add(doSomething1("1"));
            futureList.add(doSomething1("2"));
            futureList.add(doSomething1("3"));
            futureList.add(doSomething1("4"));
    
            CompletableFuture<Void> res = CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()]));
            System.out.println("main");
            // 等待所有的future执行完毕
            System.out.println(res.get());
            System.out.println("main end ");
    
        }
    
    
        public static CompletableFuture<String> doSomething1(String id) {
            return CompletableFuture.supplyAsync(new Supplier<String>() {
                @Override
                public String get() {
                    System.out.println("doSomething1 execute");
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (Exception e) {
    
                    }
                    return id;
                }
            });
        }
    
        public static CompletableFuture<String> doSomething2(String id) {
            return CompletableFuture.supplyAsync(new Supplier<String>() {
                @Override
                public String get() {
                    System.out.println("doSomething2 execute");
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (Exception e) {
    
                    }
                    return id + "doSomething2";
                }
            });
        }
    }
    
    

    package com.xsxy.asynctest.test03;
    
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.TimeUnit;
    
    public class Test03CompletableFutureWithException {
        /**
         * 之前的测试completableFuture都是基于流程正常流转,如果出现异常怎么处理
         */
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            CompletableFuture<String> future = new CompletableFuture<>();
    
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(2);
                    // 测试异常
                    if (true) {
                        throw new RuntimeException("");
                    }
                    future.complete("complete");
                } catch (Exception e) {
                    e.printStackTrace();
                    // 先注释掉, 和下边的输出语句同时放开(注释掉32,放开33)
                    // future.completeExceptionally(e);
                }
    
    
            }, "thread-1").start();
    
            System.out.println("main");
            System.out.println(future.get());
            // System.out.println(future.exceptionally(t -> "aaaaaa").get());
            System.out.println("main end");
        }
    }
    
    
  • 相关阅读:
    (dp)LeetCode Weekly Contest 34 -Non-negative Integers without Consecutive Ones
    (后缀数组)poj 3581 Sequence
    (最小生成树)Codeforces 76 A Gift
    (最小生成树)Codeforces Educational Codeforces Round 9 Magic Matrix
    (AC自动机)UVALive
    (trie)BUAAOJ 371
    CCF 201312-3 最大的矩形
    http错误代码含义
    数据结构-5-二叉树的实现以及递归遍历的实现
    数据结构-3.4-栈与队列
  • 原文地址:https://www.cnblogs.com/nxzblogs/p/12766025.html
Copyright © 2020-2023  润新知