由於使用ExecutorService
可以submit
一個Callable
任務並返回Future
,爲什麼需要使用FutureTask
包Callable
任務和使用方法execute
?我覺得他們都做同樣的事情。Future和FutureTask在Java中有什麼區別?
回答
其實你是對的。這兩種方法是相同的。你通常不需要自己包裝它們。如果你是,你可能複製代碼的AbstractExecutorService:
/**
* Returns a <tt>RunnableFuture</tt> for the given callable task.
*
* @param callable the callable task being wrapped
* @return a <tt>RunnableFuture</tt> which when run will call the
* underlying callable and which, as a <tt>Future</tt>, will yield
* the callable's result as its result and provide for
* cancellation of the underlying task.
* @since 1.6
*/
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
未來RunnableFuture之間的唯一區別,是run()方法:
/**
* A {@link Future} that is {@link Runnable}. Successful execution of
* the <tt>run</tt> method causes completion of the <tt>Future</tt>
* and allows access to its results.
* @see FutureTask
* @see Executor
* @since 1.6
* @author Doug Lea
* @param <V> The result type returned by this Future's <tt>get</tt> method
*/
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
一個很好的理由讓執行人爲您構建FutureTask的目的是確保FutureTask實例不存在多於一個引用的可能方式。也就是說,執行者擁有這個實例。
Future
只是界面。幕後,實施是FutureTask
。
您可以手動使用FutureTask
,但您將失去使用Executor
(合併線程,限制線程等)的優勢。使用FutureTask
與使用舊的Thread
和使用運行方法非常類似。
FutureTask實現Future
如果您想更改其行爲或稍後訪問其Callable,則只需使用FutureTask。對於99%的使用,只需使用Callable和Future。
FutureTask 這個類提供了base implementation of Future
,使用方法的開始和取消計算
Future是接口
正如馬克,和其他人,正確地回答Future
是FutureTask
和Executor
有效的接口其工廠;這意味着應用程序代碼很少直接實例化FutureTask
。爲了補充討論我提供表示在FutureTask
被構造並直接使用的情況下,一個示例任何Executor
外:
FutureTask<Integer> task = new FutureTask<Integer>(()-> {
System.out.println("Pretend that something complicated is computed");
Thread.sleep(1000);
return 42;
});
Thread t1 = new Thread(()->{
try {
int r = task.get();
System.out.println("Result is " + r);
} catch (InterruptedException | ExecutionException e) {}
});
Thread t2 = new Thread(()->{
try {
int r = task.get();
System.out.println("Result is " + r);
} catch (InterruptedException | ExecutionException e) {}
});
Thread t3 = new Thread(()->{
try {
int r = task.get();
System.out.println("Result is " + r);
} catch (InterruptedException | ExecutionException e) {}
});
System.out.println("Several threads are going to wait until computations is ready");
t1.start();
t2.start();
t3.start();
task.run(); // let the main thread to compute the value
這裏,FutureTask
用作同步工具,像CountdownLatch
或類似屏障原語。它可能已通過使用CountdownLatch
或鎖和條件重新實施; FutureTask
只是使它很好地封裝,不言自明,優雅,代碼少。
另請注意,FutureTask#run()方法必須在任何線程中顯式調用;那裏沒有Executor爲你做。在我的代碼中,它最終由主線程執行,但可以修改get()
方法在第一個調用get()
的線程上調用run()
,因此第一個線程到達get()
,並且它可以是T1,T2或T3中的任意一個所有剩餘線程的計算。
關於這個想法 - 第一個線程請求的結果會爲其他人計算,而併發嘗試將被阻止 - 是基於Memoizer的,請參閱「實踐中的Java併發」中第108頁的Memoizer Cache示例。
- 1. Scala Future和Java Future之間有什麼區別
- 2. future和shared_future有什麼區別?
- 3. `|。有什麼區別? `和`|| `在java中?
- 4. !=和=!有什麼區別!在Java中?
- 5. Runnable和Future在Scala之間有什麼區別?
- 6. Java中boolean和Boolean有什麼區別?
- 7. java中float和float有什麼區別?
- 8. Java中> =和=>有什麼區別?
- 9. **/*。java和* .java有什麼區別?
- 10. `java -version`和`java -showversion`有什麼區別?
- 11. java 1.5和java 1.6有什麼區別
- 12. 有什麼區別`和$(Bash中有什麼區別?
- 13. java ObjectOutputStream和OutputStream有什麼區別?
- 14. PHP和Java有什麼區別?
- 15. scala @Serializable和Java Serializable有什麼區別?
- 16. Java 8:Instant和LocalDateTime有什麼區別?
- 17. JVisualVM和Java Mission Control有什麼區別?
- 18. Eclipse for Java和RCP有什麼區別?
- 19. Java包:`oracle.AQ`和`oracle.jdbc.aq`有什麼區別?
- 20. Java EE和Asp.net有什麼區別
- 21. java 8 ZonedDateTime和OffsetDateTime有什麼區別?
- 22. Java - LibGDX - isKeyPressed和isKeyJustPressed有什麼區別?
- 23. Java RMI和RPC有什麼區別?
- 24. Java RMI和JMS有什麼區別?
- 25. 繼承和java豆有什麼區別?
- 26. JDBC和Java API有什麼區別?
- 27. java HttpsURLConnection和python HTTPSConnection有什麼區別?
- 28. 'await future'和'await asyncio.wait_for(future,None)'之間有區別嗎?
- 29. 「Future.successful(None)」和「Future(None)」之間的區別是什麼
- 30. a ++和++ a或a--和--a在java中有什麼區別?
FutureTask.get()永遠不會拋出CancellationException,而Future.get()會拋出。它是否正確?請參閱http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/FutureTask.html#get(long,java.util.concurrent.TimeUnit)。 – 2013-03-01 19:56:38