Java執行緒的基本使用(二)
阿新 • • 發佈:2019-02-13
除了通過Runnable注入以及實現Thread類的run方法之外(其實都是Runnable),java還提供了Callable、Future和FutureTask這幾個與多執行緒相關的概念,不過這幾個型別都只能用於執行緒池中。
Callable宣告如下:
public interface Callable<V>{
V call() throws Exception;
}
Callable感覺和Runnable非常相似,除了上面說的只能用於執行緒池,不同點在於Callable是一個泛型介面,允許返回一個泛型物件,同時支援丟擲異常。
public class ThreadDemo5 { public static void main(String[] args) { MyThread5<A> t1=new MyThread5<A>(); ExecutorService pool=Executors.newSingleThreadExecutor();//建立單一執行緒池 pool.submit(t1); } } abstract class BaseObject{ String str; } class A extends BaseObject{ public A(){ str="This is A."; } } class MyThread5<T extends BaseObject> implements Callable<T>{ @Override public T call() throws Exception { System.out.println("MyThread5的call方法執行"); return (T) new A(); } }
執行之後,你會發現,輸出了“MyThread5的call方法執行”,但是,要如何獲取返回值呢?
我們發現,sumbit方法返回一個Future類的物件,Future類為執行緒池提供了一些類任務標準:cancle用於對執行結果的取消;isDone用於判斷是否完成;get用於獲取callable的返回值,set用於結果設定。所以,當我們需要獲取返回值的時候,直接利用get方法即可,注意使用get方法會直接阻塞執行緒,直到獲取到對應的結果:
main函式改寫為:public static void main(String[] args) { MyThread5<A> t1=new MyThread5<A>(); ExecutorService pool=Executors.newSingleThreadExecutor();//建立單一執行緒池 Future future=pool.submit(t1); try { BaseObject a=(BaseObject)future.get(); System.out.println("str="+a.str); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
結果輸出:
MyThread5的call方法執行
str=This is A.
事實上,Future只是一個抽象介面(public abstract interfacejava.util.concurrent.Future),真正實現的類是FutureTask<T>。FutureTask的宣告為
public class java.util.concurrent.FutureTask implements java.util.concurrent.RunnableFuture
,可以看出實現了RunnableFuture介面,而RunnableFuture又繼承了Runnable 、Future介面
public abstract interface java.util.concurrent.RunnableFuture extends java.lang.Runnable,java.util.concurrent.Future
故擁有它們兩者的特點,因此,FutureTask既可以和Runnable一樣,通過Thread封裝執行,也可以交給執行緒池來執行。
public class ThreadDemo6 {
public static void main(String[] args) {
FutureTask<String> ft=new FutureTask<String>(new Callable(){
@Override
public Object call() throws Exception {
return "FutureTask 返回值";
}
});
ExecutorService pool=Executors.newSingleThreadExecutor();
pool.submit(ft);
try {
System.out.println(ft.get());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
執行結果:
FutureTask 返回值