java Future小记,自用

文章参考 Future 详解

1. Future?异步?

在这里插入图片描述
在线程池中,我们知道调用future.get()方法是会阻塞当前线程,知道得到get方法的返回值之后才继续运行,所以future是异步编程?

线程池中的提交任务的方法有两种,一个是 execute,参数是 Runnable方法,返回值是 void方法;
在这里插入图片描述
第二种方式是 submit方法:
在这里插入图片描述
有三种 submit。这三种按照提交任务的类型来算分为两个类型。

提交执行 Runnable 类型的任务。

提交执行 Callable 类型的任务。

但是返回值都是 Future,这才是我们关心的东西。

在submit中可以通过传入参数得到返回值:
示例如下:

public class ThreadPoolExecutorTest {

    public static void main(String[] args) throws Exception {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
        AtomicInteger atomicInteger = new AtomicInteger();
        Future<AtomicInteger> future = executor.submit(() -> {
            System.out.println("测试");
            //在这里进行计算逻辑
            atomicInteger.set(5201314);
        }, atomicInteger);

        System.out.println("future的内容:" + future.get());
        Thread.currentThread().join();   //防止主线程退出
    }
}

其中调用的 get()方法是阻塞的,描述可得:
在这里插入图片描述
所以总结一下这种场景下返回的 Future 的不足之处:

只有主动调用 get 方法去获取值,但是有可能值还没准备好,就阻塞等待。

任务处理过程中出现异常会把异常隐藏,封装到 Future 里面去,只有调用 get 方法的时候才知道异常了。

2. Guava 中的 Future

增加了一个监听方法,执行完成后通知!!!


public static void main(String[] args) throws InterruptedException {
        
        // 1. 初始化executor
        ListeningExecutorService executor = MoreExecutors.listeningDecorator(
                Executors.newCachedThreadPool());

        // 2. 要执行的任务
        ListenableFuture<String> listenableFuture = executor.submit(() -> {
            System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。");
            TimeUnit.SECONDS.sleep(5);
            return "化妆完毕!!";
        });

        // 3. 设置监听器函数执行回调
        listenableFuture.addListener(() -> {
            try {
                System.out.println(Thread.currentThread().getName()+"-future的内容:" + listenableFuture.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }, executor);
        // 主线程任务,不会被阻塞 
        System.out.println(Thread.currentThread().getName()+"-等女神化妆的时候可以干点自己的事情。");
        Thread.currentThread().join();
    }

另一种实现方法 FutureCallback 方式:

public class JDKThreadPoolExecutorTest {

    public static void main(String[] args) throws Exception {
        ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool());
        ListenableFuture<String> listenableFuture = executor.submit(() -> {
            System.out.println(Thread.currentThread().getName()+"-女神:我开始化妆了,好了我叫你。");
            TimeUnit.SECONDS.sleep(5);
            return "化妆完毕了。";
        });
        Futures.addCallback(listenableFuture, new FutureCallback<String>() {
            @Override
            public void onSuccess(@Nullable String result) {
                System.out.println(Thread.currentThread().getName()+"-future的内容:" + result);
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println(Thread.currentThread().getName()+"-女神放你鸽子了。");
                t.printStackTrace();
            }
        });
        System.out.println(Thread.currentThread().getName()+"-等女神化妆的时候可以干点自己的事情。");
        Thread.currentThread().join();
    }
}

在这里插入图片描述

JDK1.8的CompletableFuture

/**
     * JDK1.8 提供的用于异步编程, 类似于流编程
     */
    public static void testJDK8CompletableFuture(){

        CompletableFuture<Serializable> serializableCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。");
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "妆化好了";
            // 处理异常
        }).handleAsync((result, exception) -> {
            if (exception != null) {
                System.out.println(Thread.currentThread().getName() + "-女神放你鸽子了!");
                return exception.getCause();
            } else {
                return result;
            }
        }).thenApplyAsync((returnStr) -> {
            System.out.println(Thread.currentThread().getName() + "-" + returnStr);
            return returnStr;
        });
        System.out.println(Thread.currentThread().getName() + "-等女神化妆的时候可以干点自己的事情。");
    }

原文请看置顶连接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值