您的位置:首页 > 编程语言 > Java开发

Callable和Future、FutureTask

2015-09-24 22:25 573 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java