4.Future和 FutureTask
4.1 Future是Callable的返回結果。
它有三個功能
- 1.判斷任務是否完成
- 2.能夠中斷任務
- 3.能夠獲取任務返回結果
4.2 FutureTask
FutureTask 實現了RunnableFuture接口,RunnableFuture這個接口又繼承自Runnable和Future
因此FutureTask 既可以作為Runnable被線程執行(通過包裝Callable對象),又可以作為Future得到Callable返回值。
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
兩個構造方法,FutureTask接口是Future的唯一實現類。
實現了Callable的對象
class Task implements Callable<String> {
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(5);
System.out.println("我睡了5s");
return "success";
}
}
方法1:通過FutureTask包裝task,然后使用Thread的方式執行
public static void main(String[] args) throws InterruptedException, ExecutionException {
Task task = new Task();
/**
* 用FutureTask包裝Task對象,然后給thread去執行
*/
FutureTask<String> ft = new FutureTask<String>(task);
new Thread(ft).start();
System.out.println("主線程獲取運行結果為:"+ft.get());
}
方法2:通過FutureTask包裝task,然后使用線程池的方式執行
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newCachedThreadPool();
Task task = new Task();
/**
* 用FutureTask包裝Task對象,然后給線程池去執行
*/
FutureTask<String> ft = new FutureTask<String>(task);
Future<String> result = executorService.submit(task);
executorService.shutdown();
System.out.println("主線程獲取運行結果為:"+result.get());
}
方法3:直接使用線程池提交Callable對象
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executorService = Executors.newCachedThreadPool();
Task task = new Task();
Future<String> result = executorService.submit(task);
executorService.shutdown();
System.out.println("主線程獲取運行結果為:"+result.get());
}
總結
Future是一個接口, FutureTask類是Future 的一個實現類,并實現了Runnable,因此FutureTask可以傳遞到線程對象Thread中新建一個線程執行。所以可通過Excutor(線程池) 來執行,也可傳遞給Thread對象執行。