• 异步第一篇:异步相关接口


    Future接口

    Future表示一个异步计算任务的结果。

    Future接口方法有:

    boolean cancel(boolean mayInterruptIfRunning):取消异步运算。入参为true时,表示会取消已经开始执行的运算。为false时,不会取消已经开始执行的运算。

    boolean isCancelled():

    boolean isDone():任务结束的话,返回true,否则返回false。任务结束不仅仅指任务顺利完成,还包括任务抛异常、任务被取消等。

    V get() throws InterruptedException, ExecutionException:在主线程中获取异步运算的结果,在获取到结果之前主线程一直阻塞。如果任务执行抛异常,则get()方法会抛出ExecutionException异常。如果任务被取消,则get()会抛出CancellationException异常。

    V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException:在主线程中获取异步运算的结果,在获取到结果之前主线程阻塞,超过指定时间后会抛出TimeoutException异常。

    RunnableFuture接口

    RunnableFuture接口继承了Runnable接口和Future接口,但并未定义自己的方法。

    FutureTask是RunnableFuture实现类。FutureTask有两个构造器:FutureTask(Callable<V> callable)和FutureTask(Runnable runnable, V result)。

    TODO示例

    FutureTask的run()实例方法内部是调用Runnable实例或者Callable实例的run()方法,但是是在主线程执行,而不是在异步线程执行。这j8有啥用???

    ListenableFuture接口

    其实ListenableFuture接口有两个,但都不是jdk自带的,guava一个,spring一个。

    guava的ListenableFuture接口全类名是com.google.common.util.concurrent.ListenableFuture,继承了Future接口,只定义了一个方法:void addListener(Runnable listener, Executor executor)。常用实现类是guava的ListenableFutureTask类,全类名是com.google.common.util.concurrent.ListenableFutureTask。

    spring的ListenableFuture接口在spring-core.jar包中,全类名是org.springframework.util.concurrent.ListenableFuture,继承了Future接口,定义方法如下:

    void addCallback(ListenableFutureCallback<T> callback):注册一个ListenableFutureCallback实例。

    void addCallback(SuccessCallback<T> successCallback, FailureCallback failureCallback):注册一个SuccessCallback实例和一个failureCallback实例。

    completableFuture<T> completable():把一个spring的ListenableFuture实例转成一个jdk的CompletableFuture实例。

    spring的ListenableFuture接口常用实现类是spring的ListenableFutureTask和AsyncResult。

    guava ListenableFutureTask使用示例:

        public static void main(String[] args) {
            ExecutorService executorService = Executors.newCachedThreadPool();
            ListeningExecutorService service = MoreExecutors.listeningDecorator(executorService);
            long begin = System.currentTimeMillis();
            ListenableFuture<Boolean> booleanTask = service.submit(() -> {
                Thread.sleep(1000);
                System.out.println("1, currentThread= " + Thread.currentThread().getName());
                System.out.println("".substring(0, 1));
                return true;
            });
            booleanTask.addListener(() -> {
                try {
                    booleanTask.get();
                    Thread.sleep(2000);
                    System.out.println("2, currentThread= " + Thread.currentThread().getName());
                } catch (Exception e) {
                    System.out.println(123);
    //                e.printStackTrace();
                }
            }, executorService);
    
            Futures.addCallback(booleanTask, new FutureCallback<Boolean>() {
                @Override
                public void onSuccess(Boolean result) {
                    System.out.println("3, currentThread= " + Thread.currentThread().getName() + ", booleanTask result= " + result);
                }
    
                @Override
                public void onFailure(Throwable e) {
                    System.out.println(234);
    //                e.printStackTrace();
                }
            }, executorService);
            System.out.println("cost " + (System.currentTimeMillis() - begin) + "ms");
        }

    利用guava的MoreExecutors工具类构造出ListeningExecutorService实例,调用此实例的submit()方法即可得到一个ListenableFuture实例。接下来可以调用ListenableFuture的addListener(Runnable listener, Executor executor)方法添加一个监听任务,但这个方法说实话,不好。为什么呢?因为addListener()方法添加的监听任务不管被监听任务是否抛异常都会执行,要是想不抛异常执行一个任务,抛异常时执行另一个任务,就要用try catch把ListenableFuture实例的get()方法包裹,然后在try子句中写不抛异常时要执行的任务,catch子句中写抛异常时要执行的任务。不如用guava提供的Futures工具类,这个工具类中提供了很多静态方法,其中addCallback(ListenableFuture<V> future, FutureCallback<V> callback, Executor executor)方法可以轻松实现ListenableFuture任务抛异常和不抛异常时监听任务的不同分支。

    FluentFuture类

    FluentFuture是guava提供的类,在com.google.common.util.concurrent包中,全类名是com.google.common.util.concurrent.FluentFuture。

    待研究

    spring ListenableFutureTask使用示例:

    TODO示例

    AsyncResult类

    AsyncResult是spring提供的类,在spring-context.jar包中,全类名是org.springframework.scheduling.annotation.AsyncResult。AsyncResult实现了ListenableFuture接口。

    AsyncResult使用示例:

        public static void main(String[] args) throws NoSuchAlgorithmException {
            AsyncResult<Number> asyncResult = new AsyncResult<>(getRandom());
            asyncResult.addCallback(result -> {
                        System.out.println("result= " + result + ", currentThread= " + Thread.currentThread().getName());
                    }, e -> {
                        System.out.println("e= " + e.getMessage() + ", currentThread= " + Thread.currentThread().getName());
                    }
            );
        }
    
        private static Double getRandom() throws NoSuchAlgorithmException {
            SecureRandom secureRandom = SecureRandom.getInstanceStrong();
            return secureRandom.nextDouble();
        }

    这下终于按照预期打印了。

    CompletableFuture接口

     待研究

  • 相关阅读:
    vue整合富文本编辑器
    node.js快速入门
    springboot启动项目加载配置文件中的常量
    hihocoder1712 字符串排序(思维)
    大数运算
    hihocoder1323 回文字符串(区间dp)
    hdu6026 Deleting Edges(Dijkstra+思路)
    poj3087 Shuffle'm Up(bfs)
    hdu6024 Building Shops(区间dp)
    poj1651 Multiplication Puzzle(区间dp)
  • 原文地址:https://www.cnblogs.com/koushr/p/5873385.html
Copyright © 2020-2023  润新知