美文网首页
异步执行代码

异步执行代码

作者: 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

相关文章

  • 异步编程

    同步与异步 同步:按代码顺序依次执行 异步:先执行同步代码,完成后再执行异步代码 事件循环与消息队列:当代码执行到...

  • 异步执行代码

  • js随笔

    forEach 中不能有异步代码 否则会直接跳过异步, 先执行后续代码在执行循环内的异步代码块查阅资料后发现大概是...

  • 异步

    异步:不阻塞代码,提高执行效率同步:必须执行返回后,才能执行后面代码 异步场景:ajax,定时器(setTimeo...

  • 同步异步

    异步:不阻塞代码,提高执行效率同步:必须执行返回后,才能执行后面代码 异步场景:ajax,定时器(setTimeo...

  • 异步

    异步:不阻塞代码,提高执行效率同步:必须执行返回后,才能执行后面代码 异步场景:ajax,定时器(setTimeo...

  • 📕 史上最实用的JS笔记

    1. 同步与异步 同步和异步的区别是什么?分别举一个同步和异步的例子 同步会阻塞代码执行,而异步不会阻塞代码执行。...

  • javascript同步与异步

    先来看一段代码,输出顺序是什么呢? 答案如下: 先执行同步代码,当检测到有异步代码时,放到异步队列里等待执行。执行...

  • 循环中的异步请求结果在循环外使用问题

    场景:在一个for循环中执行异步请求,请求结果最终需要在循环外部使用。 由于异步代码执行是在主栈代码执行结束之后再...

  • 异步和单线程 - 面试题

    1:同步和异步的区别是什么?分别举一个同步和异步的例子? 答案:同步(代码从上到下执行)会阻塞代码执行,而异步不会...

网友评论

      本文标题:异步执行代码

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