一、概述:
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,TimeUnit)方法也是阻塞的,超过指定的时间,将会报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,TimeUnit)例子说明:
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
我从来不相信什么懒洋洋的自由。我向往的自由是通过勤奋和努力实现的更广阔的人生。 我要做一个自由又自律的人,靠势必实现的决心认真地活着。