在Java中,建立線程通常有兩種方式,一種是繼承Thread類,一種是實現Runnable接口。然而,這兩種方式的缺點是在線程任務執行結束後,沒法獲取執行結果。咱們通常只能採用共享變量或共享存儲區以及線程通訊的方式實現得到任務結果的目的。java
不過,Java中,也提供了使用Callable和Future來實現獲取任務結果的操做。Callable用來執行任務,產生結果,而Future用來得到結果。網絡
Callable接口的定義以下:多線程
public interface Callable<V> { /** * 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; }
與Runnable接口不一樣之處在於,call方法帶有泛型返回值V。異步
Future模式的核心在於:去除了主函數的等待時間,並使得本來須要等待的時間段能夠用於處理其餘業務邏輯ide
Futrure模式:對於多線程,若是線程A要等待線程B的結果,那麼線程A不必等待B,直到B有結果,能夠先拿到一個將來的Future,等B有結果是再取真實的結果。函數
在多線程中常常舉的一個例子就是:網絡圖片的下載,剛開始是經過模糊的圖片來代替最後的圖片,等下載圖片的線程下載完圖片後在替換。而在這個過程當中能夠作一些其餘的事情。線程
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * @author wn: * @version 上午16:53:57 * 類說明 */ public class ThreadCallTest { public static void main(String[]args){ ExecutorService executor=Executors.newCachedThreadPool(); Task task=new Task(); Future<Integer> result=executor.submit(task); if (executor != null) executor.shutdown(); try { System.out.println("call result"+result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("over"); } } class Task implements Callable<Integer>{ @Override public Integer call() throws Exception { System.out.println("3.開始 ...."); Thread.sleep(3000); System.out.println("4.結束 ...."); return "xyz"; } }
當Task啓動後不影響主線程運行,result.get()會等待3秒後返回結果xyzcode
V get() :獲取異步執行的結果,若是沒有結果可用,此方法會阻塞直到異步計算完成。繼承
V get(Long timeout , TimeUnit unit) :獲取異步執行結果,若是沒有結果可用,此方法會阻塞,可是會有時間限制,若是阻塞時間超過設定的timeout時間,該方法將拋出異常。接口
boolean isDone() :若是任務執行結束,不管是正常結束或是中途取消仍是發生異常,都返回true。 => result.isDone()
boolean isCanceller() :若是任務完成前被取消,則返回true。
boolean cancel(boolean mayInterruptRunning) :若是任務還沒開始,執行cancel(...)方法將返回false;若是任務已經啓動,執行cancel(true)方法將以中斷執行此任務線程的方式來試圖中止任務,若是中止成功,返回true;
當任務已經啓動,執行cancel(false)方法將不會對正在執行的任務線程產生影響(讓線程正常執行到完成),此時返回false;
當任務已經完成,執行cancel(...)方法將返回false。mayInterruptRunning參數表示是否中斷執行中的線程。
實際上Future提供了3種功能:
我的博客 蝸牛