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
标签:code,return,get,task,util,concurrent,future,Future 来源: https://www.cnblogs.com/lixiuming521125/p/16484678.html