1. 程式人生 > >Callable和Future、FutureTask

Callable和Future、FutureTask

Java中除了Runnable介面,還有Callable介面。
兩者區別是,後者可以有返回值,一般用於耗時計算。
Runnable介面線上程中用得比較多,一般可以作為執行緒執行體,Callable一般會與FutureTask結合使用。

Callable介面的原始碼如下:

/**
 * A task that returns a result and may throw an exception.
 * Implementors define a single method with no arguments called
 * {@code call}.
 * 帶有返回值的任務,可能丟擲異常。
 * 
 * <p>The {@code Callable} interface is similar to {@link
 * java.lang.Runnable}, in that both are designed for classes whose
 * instances are potentially executed by another thread.  A
 * {@code Runnable}, however, does not return a result and cannot
 * throw a checked exception.
 * Callable介面類似於Runnable介面,都是設計用於被其他執行緒執行的類例項。
 * 但是Runnable介面不返回結果,不能丟擲一個受檢異常。
 * 
 * <p>The {@link Executors} class contains utility methods to
 * convert from other common forms to {@code Callable} classes.
 * Executors類包含將其他通用形式轉成Callable類的輔助類。
 * 
 * @see
Executor * @since 1.5 * @author Doug Lea * @param <V> the result type of method {@code call} */
@FunctionalInterface 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; }

Future介面用於表示非同步計算的結果,該介面包含檢查計算是否結束、等待計算結束、獲取計算結果的方法。
其中get()可以獲取計算結果,在計算完成之前,會一直阻塞當前執行緒。計算可以被取消。

FutureTask實現了RunnableFuture介面:

public class FutureTask<V> implements RunnableFuture<V> {

而RunnableFuture介面繼承自Runnable和Future:

public interface RunnableFuture
<V> extends Runnable, Future<V> {

FutureTask表示可取消的非同步計算,作為Future介面的實現。FutureTask可以包裝Runnable介面,
另外因為實現了Runnable介面,所以可以提交給Executor執行。

下面用程式碼測試一下:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {

    Runnable runnable = new Runnable() {

        @Override
        public void run() {
        System.out.println("runnable running");
        }
    };

    Callable<Integer> callable = new Callable<Integer>() {

        @Override
        public Integer call() throws Exception {
        System.out.println("callable running");

        return 123;
        }
    };

    Callable<Integer> callable1 = new Callable<Integer>() {

        @Override
        public Integer call() throws Exception {
        System.out.println("callable1 running");

        return 123;
        }
    };

    //runnable
    Thread thread1 = new Thread(runnable);
    thread1.start();

    //callable
    FutureTask<Integer> future = new FutureTask<Integer>(callable);
    Thread thread2 = new Thread(future);
    thread2.start();

    System.out.println("future is done? "+future.isDone());
    //future.cancel(false);
    Thread.sleep(1000);
    System.out.println("future result: "+future.get());

    ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L,
        TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

    executor.execute(runnable);

    FutureTask<Integer> future1 = new FutureTask<Integer>(callable1);
    executor.execute(future1);

    FutureTask<String> ft = new FutureTask<String>(runnable, "aaaaa");
    Thread thread3 = new Thread(ft);
    thread3.start();
    while(!ft.isDone()){
        Thread.sleep(1000);     
    }
    System.out.println("future runnable result: "+ft.get());

    Future<Integer> futureTask = executor.submit(callable);
    while(!futureTask.isDone()){
        Thread.sleep(1000);     
    }
    System.out.println("futureTask result: "+futureTask.get());
    executor.shutdown();


    }
}

輸出結果:

runnable running
future is done? false
callable running
future result: 123
runnable running
callable1 running
runnable running
future runnable result: aaaaa
callable running
futureTask result: 123

相關推薦

CallableFutureFutureTask

Java中除了Runnable介面,還有Callable介面。 兩者區別是,後者可以有返回值,一般用於耗時計算。 Runnable介面線上程中用得比較多,一般可以作為執行緒執行體,Callable一般會與FutureTask結合使用。 Callable介面

Java中的RunnableCallableFutureFutureTask的區別CompletionService的使用場景

Java中存在Runnable、Callable、Future、FutureTask這幾個與執行緒相關的類或者介面,在Java中也是比較重要的幾個概念,我們通過下面的簡單示例來了解一下它們的作用於區別。 Runnable 其中Runnable應該是我們最

RunnableCallableExecutorFutureFutureTask關系解讀

兩個 cat util lee exceptio java5 主線程 tin [] 在再度溫習Java5的並發編程的知識點時發現,首要的就是把Runnable、Callable、Executor、Future等的關系搞明白,遂有了下述小測試程序,通過這個例子上述三者的關系就

CallableFutureFutureTask淺析

adp tac auth false strac 執行 test sin lee 1、Callable<V>接口 Runnable接口 public interface Runnable { public abstract void run();

Java並發編程之線程創建啟動(ThreadRunnableCallableFuture)

出發 row 實現 pub 發的 interrupt 指定 系列 java並發 這一系列的文章暫不涉及Java多線程開發中的底層原理以及JMM、JVM部分的解析(將另文總結),主要關註實際編碼中Java並發編程的核心知識點和應知應會部分。 說在前面,Java並發編程的實質,

Java多執行緒(ExecutorService ExecutorsCallableFutureFutureTask

前言:我們一般通過繼承Thread類重寫run方法或者實現runnable介面重寫run方法,最後建立和啟動一個執行緒,但是都需要自己建立、啟動Thread物件。執行緒池可以實現幫助我們管理Thread物件,至於要使用幾個執行緒,什麼時候啟動這些執行緒,是開啟多個執行緒還是用單個執行緒來完成

RunnableCallableExecutorFutureFutureTask關係解讀

在再度溫習Java5的併發程式設計的知識點時發現,首要的就是把Runnable、Callable、Executor、Future等的關係搞明白,遂有了下述小測試程式,通過這個例子上述三者的關係就一目瞭然了。 在java5以後,一個可以排程執行的執行緒單元可以有三種方式定義:

多執行緒下的其它元件之CyclicBarrierCallableFutureFutureTask

public static class CyclicBarrierThread extends Thread { private CyclicBarrier cb; private int sleepSecond; public CyclicBarrierThre

Java併發程式設計與技術內幕:CallableFutureFutureTaskCompletionService

         在上一文章中,筆者介紹了執行緒池及其內部的原理。今天主要講的也是和執行緒相關的內容。一般情況下,使用Runnable介面、Thread實現的執行緒我們都是無法返回結果的。但是如果對一些場合需要執行緒返回的結果。就要使用用Callable、Future、Fut

多執行緒中的RunnableCallableFutureFutureTask的作用

在Java多執行緒程式設計中,建立啟動一個執行緒可以繼承Thread類,也可以實現Runnable介面,但是想要獲取執行緒的結果,則需要實現Callable介面,獲取結果則需要使用Future介面。下面分別介紹這幾個介面或者類的實現。 Runnable介面 Runnable

Java併發程式設計之執行緒池CallableFuture使用

知識儲備 收藏幾篇好文章: 目錄結構 Callable和Future使用 執行緒池使用 Callable和Future使用 多執行緒實現方式很多,分為兩類:1、沒有返回值的;2、有返回值的。 針對“沒有返回值的”這類可以參

Java併發程式設計實踐:Callable非同步回撥FutureFutureTask用法

Callable介面類似於Runnable,從名字就可以看出來了,但是Runnable不會返回結果,並且無法丟擲返回結果的異常,而Callable功能更強大一些,被執行緒執行後,可以返回值,這個返回值可以被Future拿到。FutureTask實現了兩個介面,Runnable

CallableFuture用法示例

Callable FutureCallable和Future用法示例: 1.Callable 和 Future接口 Callable是類似於Runnable的接口,實現Callable接口的類和實現Runnable的類都是可被其它線程執行的任務。 Callable和Runnable有幾點不同: (1)Ca

Java多線程CallableFuture類詳解

完成後 使用 str this In ret 類型 all 線程池 public interface Callable<V> 返回結果並且可能拋出異常的任務。實現者定義了一個不帶任何參數的叫做 call 的方法 public inter

【小家Java】FutureFutureTaskCompletionServiceCompletableFuture解決多執行緒併發中歸集問題的效率對比

相關閱讀 【小家java】java5新特性(簡述十大新特性) 重要一躍 【小家java】java6新特性(簡述十大新特性) 雞肋升級 【小家java】java7新特性(簡述八大新特性) 不溫不火 【小家java】java8新特性(簡述十大新特性) 飽受讚譽 【小家java】java9

多執行緒學習---CallableFuture的使用(十)

1.Callable和Future適用於帶有返回結果的多執行緒 示例 public class CallAndFutureStudy { public static void main(String[] args) { ExecutorService threadPool

併發-9-CallableFuture

我們原來所說的繼承Thread或者實現Runnable的方式都無法獲得執行緒的執行結果,除非使用共享變數或者執行緒通訊,我們先看一下Runnable介面的原始碼: public interface Runnable{ public abstract void run(){ } } 複製程式碼

Java多線程系列--“JUC線程池”06之 CallableFuture

done ecan 對象 ava running 轉載 end 基於 處理 轉自:http://www.cnblogs.com/skywang12345/p/3544116.html 概要 本章介紹線程池中的Callable和Future。 Callable 和 Futu

CallableFuture 執行緒

Callable和Future出現的原因 建立執行緒的2種方式,一種是直接繼承Thread,另外一種就是實現Runnable介面。  這2種方式都有一個缺陷就是:在執行完任務之後無法獲取執行結果。  如果需要獲取執行結果,就必須通過共享變數或者使用執行緒通訊的方式來達到效果

FutureFutureTask實現原理淺析

前言 最近一直在看JUC下面的一些東西,發現很多東西都是以前用過,但是真是到原理層面自己還是很欠缺。 剛好趁這段時間不太忙,回來了便一點點學習總結。 由於自己水平有限,可能存在大量漏洞和思考不周到的地方,不吝賜教。 另外本文章首發本人部落格園: 部落格園地址 Future 模式