1. 程式人生 > >Callable、Future、FutureTask淺析

Callable、Future、FutureTask淺析

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)將不會對執行線程產生影響,此時返回false
boolean 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淺析