java终结方法_Java终结任务:Callable和Future
在這里首先介紹下Callable和Future,我們知道通常創建線程的2種方式,一種是直接繼承Thread,另外一種就是實現Runnable接口,但是這兩種方式創建的線程不返回結果,而Callable是和Runnable類似的接口定義,但是通過實現Callable接口創建的線程可以有返回值,返回值類型可以任意定義。
Callable接口
public interface Callable {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
可以看到,這是一個泛型接口,call()函數返回的類型就是傳遞進來的V類型。
那么怎么使用Callable呢?一般情況下是配合ExecutorService來使用的,在ExecutorService接口中聲明了若干個submit方法的重載版本:
Future submit(Callable task);
Future submit(Runnable task, T result);
Future> submit(Runnable task);
第一個submit方法里面的參數類型就是Callable。Callable一般是和ExecutorService配合來使用的,通過ExecutorService的實例submit得到Future對象。
Future
Future接口如下:
public interface Future {
boolean cancel(boolean mayInterruptIfRunning);// 試圖取消對此任務的執行
boolean isCancelled(); // 如果在任務正常完成前將其取消,則返回true
boolean isDone(); // 如果任務已完成(不管是正常還是異常),則返回true
V get() throws InterruptedException, ExecutionException; // 方法用來獲取執行結果,這個方法會產生阻塞,會一直等到任務執行完畢才返回;
// 用來獲取執行結果,如果在指定時間內,還沒獲取到結果,就直接返回null;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}
Future用于表示異步計算的結果。它的實現類是FutureTask。
如果不想分支線程阻塞主線程,又想取得分支線程的執行結果,就用FutureTask
FutureTask實現了RunnableFuture接口,這個接口的定義如下:
public interface RunnableFuture extends Runnable, Future
{
void run();
}
可以看出RunnableFuture繼承了Runnable接口和Future接口,而FutureTask實現了RunnableFuture接口。所以它既可以作為Runnable被線程執行,又可以作為Future得到Callable的返回值。
使用示例
package demo.future;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* 試驗 Java 的 Future 用法
*/
public class FutureTest {
public static class Task implements Callable {
@Override
public String call() throws Exception {
String tid = String.valueOf(Thread.currentThread().getId());
System.out.printf("Thread#%s : in call\n", tid);
return tid;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
List> results = new ArrayList>();
ExecutorService es = Executors.newCachedThreadPool();
for(int i=0; i<100;i++)
results.add(es.submit(new Task()));
for(Future res : results)
System.out.println(res.get());
}
}
終結任務
持有Future對象,可以調用cancel(),并因此可以使用它來中斷某個特定任務,如果將ture傳遞給cancel(),那么它就會擁有該線程上調用interrupt()以停止這個線程的權限。因此,cancel()是一種中斷由Executor啟動的單個線程的方式。
cancel()一般是搭配get()方法來使用的。比方說,有一種設計模式是設定特定的時間,然后去執行一個作業的線程,如果該作業能夠在設定的時間內執行完畢,則直接返回結果,如果不能執行完畢,則中斷作業的執行,繼續執行下一個作業,在這種模式下,使用Callable和Future來實現是一個非常好的解決方案。
總結
以上是生活随笔為你收集整理的java终结方法_Java终结任务:Callable和Future的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习入门(1)之基本概念简介
- 下一篇: android汽车音频焦点方案,管理音频