Callable、Future、FutureTask淺析
阿新 • • 發佈:2018-03-14
adp tac auth false strac 執行 test sin lee
1、Callable<V>接口
Runnable接口
public interface Runnable { public abstract void run(); }
Callable
public interface Callable<V> { V call() throws Exception; }
runnable接口 Callable接口 都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor執行,兩者實現了ExcutorService接口
ExecutorService接口
<T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task);
2、Future<V>
獲得異步計算結果,說白了就是對具體的Runnable或者Callable對象任務執行的結果進行獲取(get()),取消(cancel()),判斷是否完成等操作。
public interface Future<V> {
//如果任務沒開始,cancle()將會返回true
//如果任務已經啟動,執行cancle(true)將以中斷執行此任務線程的方式來試圖阻止任務,成功返滬true
//如果任務已經啟動,執行cancle(false)將不會對執行線程產生影響,此時返回falseboolean cancel(boolean mayInterruptIfRunning);
//如果任務完成前被取消,返回true boolean isCancelled();
//如果任務結束,無論是正常結束或是中途取消還是發生異常,都會true boolean isDone();
//獲取異步執行結果,如果沒有結果可用,此方法會阻塞直到異步計算完成。 V get() throws InterruptedException, ExecutionException;
//獲取異步執行結果,如果沒有結果可用,此方法會阻塞,
//但是會有時間限制,如果阻塞時間超過設定的timeout時間,該方法將拋出異常。 V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
3、FutureTask類
public class FutureTask<V> implements RunnableFuture<V> {
其中
public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); }
構造方法:
public interface RunnableFuture<V> extends Runnable, Future<V> { void run(); }
使用場景:
1、使用Callable+Future獲取執行結果
package com.zejian.Executor; import java.util.concurrent.Callable; /** * @author zejian * @time 2016年3月15日 下午2:02:42 * @decrition Callable接口實例 */ public class CallableDemo implements Callable<Integer> { private int sum; @Override public Integer call() throws Exception { System.out.println("Callable子線程開始計算啦!"); Thread.sleep(2000); for(int i=0 ;i<5000;i++){ sum=sum+i; } System.out.println("Callable子線程計算結束!"); return sum; } }
package com.zejian.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * @author zejian * @time 2016年3月15日 下午2:05:43 * @decrition callable執行測試類 */ public class CallableTest { public static void main(String[] args) { //創建線程池 ExecutorService es = Executors.newSingleThreadExecutor(); //創建Callable對象任務 CallableDemo calTask=new CallableDemo(); //提交任務並獲取執行結果 Future<Integer> future =es.submit(calTask); //關閉線程池 es.shutdown(); try { Thread.sleep(2000); System.out.println("主線程在執行其他任務"); if(future.get()!=null){ //輸出獲取到的結果 System.out.println("future.get()-->"+future.get()); }else{ //輸出獲取到的結果 System.out.println("future.get()未獲取到結果"); } } catch (Exception e) { e.printStackTrace(); } System.out.println("主線程在執行完成"); } }
執行結果:
Callable子線程開始計算啦! 主線程在執行其他任務 Callable子線程計算結束! future.get()-->12497500 主線程在在執行完成
2、使用Callable+FutureTask獲取執行結果
package com.zejian.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; /** * @author zejian * @time 2016年3月15日 下午2:05:43 * @decrition callable執行測試類 */ public class CallableTest { public static void main(String[] args) { //創建線程池 ExecutorService es = Executors.newSingleThreadExecutor(); //創建Callable對象任務 CallableDemo calTask=new CallableDemo(); //創建FutureTask FutureTask<Integer> futureTask=new FutureTask<>(calTask); //執行任務 es.submit(futureTask); //關閉線程池 es.shutdown(); try { Thread.sleep(2000); System.out.println("主線程在執行其他任務"); if(futureTask.get()!=null){ //輸出獲取到的結果 System.out.println("futureTask.get()-->"+futureTask.get()); }else{ //輸出獲取到的結果 System.out.println("futureTask.get()未獲取到結果"); } } catch (Exception e) { e.printStackTrace(); } System.out.println("主線程在執行完成"); } }
結果:
Callable子線程開始計算啦! 主線程在執行其他任務 Callable子線程計算結束! futureTask.get()-->12497500 主線程在執行完成
Callable、Future、FutureTask淺析