Java中的Callable和Future

Java中的Callable和Future

Java中的Runnable接口与线程相关,将实现该接口的对象作为参数传入Thread类。但是实现Runnable接口中的run方法没有返回值,同时没有checked exception。

Callable接口对Runnable接口的补充,Callable接口中的call()返回值与其泛型类型相同,同时有checked exception。我们将实现Callable接口的对象进一步封装成Future类型的对象,最后将该对象传入Thread类中,开启线程。我们可以通过Future类型的对象来获取异步计算Callable的call()方法的结果,通过调用Future类型的对象的get()方法来获取结果。

官方文档对Callable和Future的介绍如下:

public interface Callable

A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call.
The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A Runnable, however, does not return a result and cannot throw a checked exception.

The Executors class contains utility methods to convert from other common forms to Callable classes.


public interface Future

A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready. Cancellation is performed by the cancel method. Additional methods are provided to determine if the task completed normally or was cancelled. Once a computation has completed, the computation cannot be cancelled. If you would like to use a Future for the sake of cancellability but not provide a usable result, you can declare types of the form Future

package test2;

import java.util.concurrent.Callable;

/**
 * Created by siege on 2015-09-15.
 */
public class Test implements Callable<String> {

    @Override
    public String call() throws Exception {
        return "siege";
    }
}



package test2;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Created by siege on 2015-09-15.
 */
public class MyTest {

    public static void main(String[] args) {
        FutureTask<String> future=new FutureTask(new Test());
        Thread thread=new Thread(future);
        thread.start();
        try {
            System.out.println(future);
            String name=future.get();
            System.out.println(name);
            System.out.println(future.isDone());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

返回结果:

java.util.concurrent.FutureTask@74a14482
siege
true

或者我们使用ExecutorService:

package test2;

import java.util.concurrent.*;

/**
 * Created by siege on 2015-09-15.
 */
public class HelloWorldApp {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService es= Executors.newSingleThreadExecutor();


        System.out.println("submitted callable task to calculate factorial of 10");
        Future result10=es.submit(new FactorialCalculator(10));

        System.out.println("submitted callable task to calculate factorial of 15");
        Future result15 = es.submit(new FactorialCalculator(15));

        System.out.println("submitted callable task to calculate factorial of 20");
        Future result20 = es.submit(new FactorialCalculator(20));

        System.out.println("Calling get method of Future to fetch result of factorial 10");
        long factorialof10 = (long) result10.get();
        System.out.println("factorial of 10 is : " + factorialof10);

        System.out.println("Calling get method of Future to get result of factorial 15");
        long factorialof15 = (long) result15.get();
        System.out.println("factorial of 15 is : " + factorialof15);

        System.out.println("Calling get method of Future to get result of factorial 20");
        long factorialof20 = (long) result20.get();
        System.out.println("factorial of 20 is : " + factorialof20);
    }
}

class FactorialCalculator implements Callable<Long>{
    private int number;

    public FactorialCalculator(int number) {
        this.number = number;
    }


    @Override
    public Long call() throws Exception {
        return factorial(number);
    }

    private long factorial(int n) {
        long result=1;
        while (n!=0){
            result=result*n;
            n--;
        }
        return result;
    }
}

结果为:

submitted callable task to calculate factorial of 10
submitted callable task to calculate factorial of 15
submitted callable task to calculate factorial of 20
Calling get method of Future to fetch result of factorial 10
factorial of 10 is : 3628800
Calling get method of Future to get result of factorial 15
factorial of 15 is : 1307674368000
Calling get method of Future to get result of factorial 20
factorial of 20 is : 2432902008176640000

猜你喜欢

转载自blog.csdn.net/u010999240/article/details/48476449