ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java.util.concurrent之future

2022-07-16 17:35:59  阅读:164  来源: 互联网

标签:code return get task util concurrent future Future


一、概述:

Future用来获取异步执行的结果。只要一个方法返回一个future,那么他就是一个异步方法;如下Junit方法,执行test,打印"我是test方法",过了10秒以后,打印Hello world;说明invoke 就是一个异步方法;

@Test
    public void test() {
        Future<String> future = invoke();
        System.out.println("我是test方法");
        try {
            String str = future.get();
            System.out.println(str);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public Future<String> invoke() {
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        Future<String> future = executorService.submit(() -> {
            // ...
            Thread.sleep(10000l);
            return "Hello world";
        });
        return future;

    }

二、future 接口方法说明:

1.future接口:

  1 package java.util.concurrent;
  2 
  3 /**
  4  * A {@code Future} represents the result of an asynchronous
  5  * computation.  Methods are provided to check if the computation is
  6  * complete, to wait for its completion, and to retrieve the result of
  7  * the computation.  The result can only be retrieved using method
  8  * {@code get} when the computation has completed, blocking if
  9  * necessary until it is ready.  Cancellation is performed by the
 10  * {@code cancel} method.  Additional methods are provided to
 11  * determine if the task completed normally or was cancelled. Once a
 12  * computation has completed, the computation cannot be cancelled.
 13  * If you would like to use a {@code Future} for the sake
 14  * of cancellability but not provide a usable result, you can
 15  * declare types of the form {@code Future<?>} and
 16  * return {@code null} as a result of the underlying task.
 17  *
 18  * <p>
 19  * <b>Sample Usage</b> (Note that the following classes are all
 20  * made-up.)
 21  * <pre> {@code
 22  * interface ArchiveSearcher { String search(String target); }
 23  * class App {
 24  *   ExecutorService executor = ...
 25  *   ArchiveSearcher searcher = ...
 26  *   void showSearch(final String target)
 27  *       throws InterruptedException {
 28  *     Future<String> future
 29  *       = executor.submit(new Callable<String>() {
 30  *         public String call() {
 31  *             return searcher.search(target);
 32  *         }});
 33  *     displayOtherThings(); // do other things while searching
 34  *     try {
 35  *       displayText(future.get()); // use future
 36  *     } catch (ExecutionException ex) { cleanup(); return; }
 37  *   }
 38  * }}</pre>
 39  *
 40  * The {@link FutureTask} class is an implementation of {@code Future} that
 41  * implements {@code Runnable}, and so may be executed by an {@code Executor}.
 42  * For example, the above construction with {@code submit} could be replaced by:
 43  *  <pre> {@code
 44  * FutureTask<String> future =
 45  *   new FutureTask<String>(new Callable<String>() {
 46  *     public String call() {
 47  *       return searcher.search(target);
 48  *   }});
 49  * executor.execute(future);}</pre>
 50  *
 51  * <p>Memory consistency effects: Actions taken by the asynchronous computation
 52  * <a href="package-summary.html#MemoryVisibility"> <i>happen-before</i></a>
 53  * actions following the corresponding {@code Future.get()} in another thread.
 54  *
 55  * @see FutureTask
 56  * @see Executor
 57  * @since 1.5
 58  * @author Doug Lea
 59  * @param <V> The result type returned by this Future's {@code get} method
 60  */
 61 public interface Future<V> {
 62 
 63     /**
 64      * Attempts to cancel execution of this task.  This attempt will
 65      * fail if the task has already completed, has already been cancelled,
 66      * or could not be cancelled for some other reason. If successful,
 67      * and this task has not started when {@code cancel} is called,
 68      * this task should never run.  If the task has already started,
 69      * then the {@code mayInterruptIfRunning} parameter determines
 70      * whether the thread executing this task should be interrupted in
 71      * an attempt to stop the task.
 72      *
 73      * <p>After this method returns, subsequent calls to {@link #isDone} will
 74      * always return {@code true}.  Subsequent calls to {@link #isCancelled}
 75      * will always return {@code true} if this method returned {@code true}.
 76      *
 77      * @param mayInterruptIfRunning {@code true} if the thread executing this
 78      * task should be interrupted; otherwise, in-progress tasks are allowed
 79      * to complete
 80      * @return {@code false} if the task could not be cancelled,
 81      * typically because it has already completed normally;
 82      * {@code true} otherwise
 83      */
 84     boolean cancel(boolean mayInterruptIfRunning);
 85 
 86     /**
 87      * Returns {@code true} if this task was cancelled before it completed
 88      * normally.
 89      *
 90      * @return {@code true} if this task was cancelled before it completed
 91      */
 92     boolean isCancelled();
 93 
 94     /**
 95      * Returns {@code true} if this task completed.
 96      *
 97      * Completion may be due to normal termination, an exception, or
 98      * cancellation -- in all of these cases, this method will return
 99      * {@code true}.
100      *
101      * @return {@code true} if this task completed
102      */
103     boolean isDone();
104 
105     /**
106      * Waits if necessary for the computation to complete, and then
107      * retrieves its result.
108      *
109      * @return the computed result
110      * @throws CancellationException if the computation was cancelled
111      * @throws ExecutionException if the computation threw an
112      * exception
113      * @throws InterruptedException if the current thread was interrupted
114      * while waiting
115      */
116     V get() throws InterruptedException, ExecutionException;
117 
118     /**
119      * Waits if necessary for at most the given time for the computation
120      * to complete, and then retrieves its result, if available.
121      *
122      * @param timeout the maximum time to wait
123      * @param unit the time unit of the timeout argument
124      * @return the computed result
125      * @throws CancellationException if the computation was cancelled
126      * @throws ExecutionException if the computation threw an
127      * exception
128      * @throws InterruptedException if the current thread was interrupted
129      * while waiting
130      * @throws TimeoutException if the wait timed out
131      */
132     V get(long timeout, TimeUnit unit)
133         throws InterruptedException, ExecutionException, TimeoutException;
134 }
View Code

2.cancel && isCancelled:

  • 假设触发了一个任务,但由于某种原因,不再关心结果。 可以使用 Future.cancel(boolean) 告诉 executor 停止操作并中断其底层线程。且该线程状态为执行完成:
  • isCancelled,可以判断线程是否被取消;该方法为同步方法,即调用该方法立即返回一个结果;

如下代码,则结果是:

是否取消:true

java.util.concurrent.CancellationException...异常

该异常是以为线程已经取消,结果中没有值导致异常;

 1     @Test
 2     public void test1() {
 3         Future<String> future = invoke();
 4         future.cancel(true);
 5         System.out.println("是否取消:" + future.isCancelled());
 6         try {
 7             String str = future.get();
 8             System.out.println(str);
 9         } catch (Exception e) {
10             e.printStackTrace();
11         }
12     }

如果取消放在执行future完成后面,则无法取消;如下代码运行结果:

Hello world

是否取消:false

 1     @Test
 2     public void test() {
 3         Future<String> future = invoke();
 4         try {
 5             String str = future.get();
 6             System.out.println(str);
 7         } catch (Exception e) {
 8             e.printStackTrace();
 9         }
10         future.cancel(true);
11         System.out.println("是否取消:" + future.isCancelled());
12     }

3.get & isDone

isDone:判断该方法是否执行完成,该方法为同步的,也就是说调用该方法时,立即返回一个结果;

get() 方法是阻塞的,也就是说,执行future.get(),该条语句需要等待future方法执行结束才能再往下执行;

get(long timeout, TimeUnit unit)方法也是阻塞的,超过指定的时间,将会报TimeoutException。也就是说,他只等future方法 timeout 秒时间,超过这个时间,future方法还想执行结束就报错;

 1 @Test
 2     public void test() {
 3         Future<String> future = invoke();
 4         System.out.println("是否执行完成:" + future.isDone());
 5         try {
 6             // String str = future.get(100, TimeUnit.SECONDS);
 7             String str = future.get();
 8             System.out.println(str);
 9         } catch (Exception e) {
10             e.printStackTrace();
11         }
12         System.out.println("是否执行完成:" + future.isDone());
13     }

上面代码执行结果为:

是否执行完成:false

Hello world

是否执行完成:true

Hello world 和 上面打印的语句时间间隔了10s以上;

4.get(long timeout, TimeUnit unit)例子说明:

 1 @Test
 2     public void test() {
 3         Future<String> future = invoke();
 4         System.out.println("是否执行完成:" + future.isDone());
 5         try {
 6             String str = future.get(9, TimeUnit.SECONDS);
 7             System.out.println(str);
 8         } catch (Exception e) {
 9             e.printStackTrace();
10         }
11         System.out.println("是否执行完成:" + future.isDone());
12     }

改代码执行结果为:

是否执行完成:false

java.util.concurrent.TimeoutException...

是否执行完成:false

标签:code,return,get,task,util,concurrent,future,Future
来源: https://www.cnblogs.com/lixiuming521125/p/16484678.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有