java.util.concurrent之future

2022/7/17 1:16:32

本文主要是介绍java.util.concurrent之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



这篇关于java.util.concurrent之future的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程