美文网首页
异步执行代码

异步执行代码

作者: AC编程 | 来源:发表于2021-11-01 14:13 被阅读0次

    一、CompletableFuture

    1.1 supplyAsync异步执行,不取返回值-指定线程池

    代码

    public class SupplyAsyncTest {
        /**
         * supplyAsync异步执行,不取返回值-指定线程池
         */
        public static void main(String[] args) {
            System.out.println(Thread.currentThread() + " 主线程-开始,time->" + getTime());
    
            CompletableFuture.supplyAsync(() -> {
                System.out.println("子线程-是否为守护线程:" + Thread.currentThread().isDaemon());
                System.out.println(Thread.currentThread() + " 子线程-开始,time->" + getTime());
    
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                System.out.println(Thread.currentThread() + " 子线程-退出,time->" + getTime());
    
                return "AlanChen";
            }, GlobalThreadPool.getExecutor());
    
            System.out.println(Thread.currentThread() + " 主线程-退出,time->" + getTime());
        }
    
        private static String getTime() {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            return formatter.format(new Date());
        }
    }
    

    执行结果

    Thread[main,5,main] 主线程-开始,time->2022-02-16 17:58:52 557
    Thread[main,5,main] 主线程-退出,time->2022-02-16 17:58:52 594
    子线程-是否为守护线程:false
    Thread[pool-1-thread-1,5,main] 子线程-开始,time->2022-02-16 17:58:52 595
    Thread[pool-1-thread-1,5,main] 子线程-退出,time->2022-02-16 17:58:54 600
    
    Process finished with exit code 0
    

    supplyAsync()方法和runAsync()方法一样有守护线程的问题,因此我们调用时指定线程池,而不用默认的线程池。

    1.2 supplyAsync异步执行,同步取返回值-get

    代码

    public class SupplyAsyncTest2 {
        /**
         *  supplyAsync异步执行,同步取返回值
         */
        public static void main(String[] args) {
            System.out.println(Thread.currentThread() + " 主线程-开始,time->" + getTime());
    
            CompletableFuture<String> completableFuture =CompletableFuture.supplyAsync(() -> {
                System.out.println("子线程-是否为守护线程:" + Thread.currentThread().isDaemon());
                System.out.println(Thread.currentThread() + " 子线程-开始,time->" + getTime());
    
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                System.out.println(Thread.currentThread() + " 子线程-退出,time->" + getTime());
    
                return "AlanChen";
            }, GlobalThreadPool.getExecutor());
    
            // 中间可以先执行一堆逻辑,再阻塞获取返回结果
            System.out.println("中间可以先执行一堆逻辑,再阻塞获取返回结果");
    
            try {
                //阻塞获取返回结果
                System.out.println("异步执行返回结果:" + completableFuture.get());
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            System.out.println(Thread.currentThread() + " 主线程-退出,time->" + getTime());
        }
    
        private static String getTime() {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            return formatter.format(new Date());
        }
    }
    

    执行结果

    Thread[main,5,main] 主线程-开始,time->2022-02-16 18:02:45 956
    中间可以先执行一堆逻辑,再阻塞获取返回结果
    子线程-是否为守护线程:false
    Thread[pool-1-thread-1,5,main] 子线程-开始,time->2022-02-16 18:02:46 000
    Thread[pool-1-thread-1,5,main] 子线程-退出,time->2022-02-16 18:02:48 008
    异步执行返回结果:AlanChen
    Thread[main,5,main] 主线程-退出,time->2022-02-16 18:02:48 009
    
    1.3 supplyAsync异步执行,异步取返回值-whenCompleteAsync

    代码

    public class SupplyAsyncTest3 {
        /**
         * supplyAsync异步执行,异步取返回值
         */
        public static void main(String[] args) {
            System.out.println(Thread.currentThread() + " 主线程-开始,time->" + getTime());
    
            CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
                System.out.println("子线程-是否为守护线程:" + Thread.currentThread().isDaemon());
                System.out.println(Thread.currentThread() + " 子线程-开始,time->" + getTime());
    
                try {
                    Thread.sleep(2000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                //int a=1/0;
    
                System.out.println(Thread.currentThread() + " 子线程-退出,time->" + getTime());
    
                return "AlanChen";
            }, GlobalThreadPool.getExecutor());
    
            // 中间可以执行一堆逻辑
            System.out.println("中间可以执行一堆逻辑");
    
            //异步回调获取返回值
            completableFuture.whenCompleteAsync((result, e) -> {
                System.out.println("-------异步执行返回结果:" + result);
                System.out.println("-------e=" + e);
            }).exceptionally(f -> {
                System.out.println("-----exception:" + f.getMessage());
                return "出现异常后的返回值";
            });
    
            System.out.println(Thread.currentThread() + " 主线程-退出,time->" + getTime());
        }
    
        private static String getTime() {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            return formatter.format(new Date());
        }
    }
    

    执行结果

    Thread[main,5,main] 主线程-开始,time->2022-02-16 18:12:45 109
    中间可以执行一堆逻辑
    子线程-是否为守护线程:false
    Thread[pool-1-thread-1,5,main] 子线程-开始,time->2022-02-16 18:12:45 149
    Thread[main,5,main] 主线程-退出,time->2022-02-16 18:12:45 150
    Thread[pool-1-thread-1,5,main] 子线程-退出,time->2022-02-16 18:12:47 159
    -------异步执行返回结果:AlanChen
    -------e=null
    

    二、Future

    2.1 Future异步执行,不需要取返回值

    代码

    public class FutureTest {
        /**
         * Future异步执行,不需要取返回值
         */
        public static void main(String[] args) {
            System.out.println(Thread.currentThread() + " 主线程-开始,time->" + getTime());
    
            ExecutorService executor = Executors.newFixedThreadPool(3);
    
            executor.submit(() -> {
                System.out.println("子线程-是否为守护线程:" + Thread.currentThread().isDaemon());
                System.out.println(Thread.currentThread() + " 子线程-开始,time->" + getTime());
    
                Thread.sleep(2000);
    
                System.out.println(Thread.currentThread() + " 子线程-退出,time->" + getTime());
    
                return "AlanChen";
            });
    
            System.out.println(Thread.currentThread() + " 主线程-退出,time->" + getTime());
        }
    
        private static String getTime() {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            return formatter.format(new Date());
        }
    }
    

    执行结果

    Thread[main,5,main] 主线程-开始,time->2022-02-16 16:44:29 719
    子线程-是否为守护线程:false
    Thread[main,5,main] 主线程-退出,time->2022-02-16 16:44:29 756
    Thread[pool-1-thread-1,5,main] 子线程-开始,time->2022-02-16 16:44:29 756
    Thread[pool-1-thread-1,5,main] 子线程-退出,time->2022-02-16 16:44:31 761
    
    2.2 Future异步执行,取返回值

    代码

    public class FutureTest2 {
        /**
         * Future异步执行,取返回值
         */
        public static void main(String[] args) {
            System.out.println(Thread.currentThread() + " 主线程-开始,time->" + getTime());
    
            ExecutorService executor = Executors.newFixedThreadPool(3);
    
            Future future = executor.submit(() -> {
                System.out.println("子线程-是否为守护线程:" + Thread.currentThread().isDaemon());
                System.out.println(Thread.currentThread() + " 子线程-开始,time->" + getTime());
    
                Thread.sleep(2000);
    
                System.out.println(Thread.currentThread() + " 子线程-退出,time->" + getTime());
    
                return "AlanChen";
            });
    
            // 中间可以先执行一堆逻辑,再阻塞获取返回结果
            System.out.println("中间可以先执行一堆逻辑,再阻塞获取返回结果");
    
            try {
                //阻塞获取返回结果
                System.out.println("异步执行返回结果:" + future.get());
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            System.out.println(Thread.currentThread() + " 主线程-退出,time->" + getTime());
        }
    
        private static String getTime() {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
            return formatter.format(new Date());
        }
    }
    

    执行结果

    Thread[main,5,main] 主线程-开始,time->2022-02-16 16:49:19 027
    中间可以先执行一堆逻辑,再阻塞获取返回结果
    子线程-是否为守护线程:false
    Thread[pool-1-thread-1,5,main] 子线程-开始,time->2022-02-16 16:49:19 070
    Thread[pool-1-thread-1,5,main] 子线程-退出,time->2022-02-16 16:49:21 079
    异步执行返回结果:AlanChen
    Thread[main,5,main] 主线程-退出,time->2022-02-16 16:49:21 080
    

    相关文章

      网友评论

          本文标题:异步执行代码

          本文链接:https://www.haomeiwen.com/subject/dxvzaltx.html