异步执行代码

2021-11-01  本文已影响0人  AC编程

一、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
上一篇下一篇

猜你喜欢

热点阅读