天天看點

Callable接口探究

一種具有類型參數的泛型,類型參數表示的是從call()中傳回的值)

建立接口的思路

1)建立Callable實作類+重寫call;

2)借助執行排程服務ExecutorService,擷取Future對象:

-ExecutorService ser = Executors。newFixedThreadpool(2);

-Future result = ser.submit(實作類對象)

3)擷取值result.get()

4)停止服務ser.shutdownNow()

(通常跟ExecutorService配合使用)

public class Callabletest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //建立線程
        ExecutorService ser = Executors.newFixedThreadPool(1);
        Race race = new Race();
        //擷取值
        Future<Integer> result = ser.submit(race);
        int num = result.get();
        System.out.println(num);
        ser.shutdown();
    }
}


class Race implements Callable<Integer> {
    private String name;
    public Integer call() throws Exception {
        return 1000;
    }      

這種方式建立線程優點:

1)可以擷取傳回值

2)可以對外申明異常

Callable和Future的關系:

Callable接口代表了一段可以被線程執行的代碼,而Future接口用于接收或是控制檢視該線程的結果或是過程。Callable用于産生結果,而Future用于接受結果。Callable接口使用泛型去定義它的傳回類型,Future也使用泛型去接收它的接收類型。Executors類提供了一些有用的方法線上程池中執行Callable内的任務。由于Callable任務是并行的(并行就是整體看上去是并行的,其實在某個時間點隻有一個線程在執行),我們必須等待它傳回的結果。 Java.util.concurrent.Future對象為我們解決了這個問題。線上程池送出Callable任務後傳回了一個Future對象,使用它可以知道Callable任務的狀态和得到Callable傳回的執行結果。Future提供了get()方法讓我們可以等待Callable結束并擷取它的執行結果。

一、Runnable(interface)

public interface Runnable {

public void run();

}

run()方法傳回值為void類型,是以在執行完任務之後無法傳回任何結果。

二、Callable (interface)

public interface Callable {

V call() throws Exception;

與 Runnable 不同的是call()函數傳回的類型就是傳遞進來的V類型,而且能夠抛出異常。一般情況下是配合ExecutorService來使用的

三、Future( interface)

Future是對于具體的Runnable或者Callable任務的執行結果進行取消、查詢是否完成、擷取結果、設定結果操作。

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}      

cancel方法用來取消任務,如果取消任務成功則傳回true,如果取消任務失敗則傳回false。參數mayInterruptIfRunning表示是否允許取消正在執行卻沒有執行完畢的任務,如果設定true,則表示可以取消正在執行過程中的任務。如果任務已經完成,則無論mayInterruptIfRunning為true還是false,此方法肯定傳回false,即如果取消已經完成的任務會傳回false;如果任務正在執行,若mayInterruptIfRunning設定為true,則傳回true,若mayInterruptIfRunning設定為false,則傳回false;如果任務還沒有執行,則無論mayInterruptIfRunning為true還是false,肯定傳回true。

isCancelled方法表示任務是否被取消成功,如果在任務正常完成前被取消成功,則傳回 true。

isDone方法表示任務是否已經完成,若任務完成,則傳回true;

get()方法用來擷取執行結果,這個方法會産生阻塞,會一直等到任務執行完畢才傳回;

get(long timeout, TimeUnit unit)用來擷取執行結果,如果在指定時間内,還沒擷取到結果,就直接傳回null。

也就是說Future提供了三種功能:

判斷任務是否完成;

能夠中斷任務;

能夠擷取任務執行結果。

四.ExecutorService

必須使用ExecutorService.submit()方法調用

提供了三種重載的submit方法如下(第二種不常用):

Future submit(Callable task);

//送出一個傳回值的任務用于執行,傳回一個表示任務的未決結果的 Future。

Future submit(Runnable task, T result);

//送出一個 Runnable 任務用于執行,并傳回一個表示該任務的 Future。

Future