Callable与Runable
在Java5之前我们进行线程的创建都是使用Runable接口,实现其中的run方法,自从有了java.util.concurrent这个包后,我们就多了一种选择,并发执行器Executors可以运行开发者使用Callable来创建线程任务,如下:
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
再看看之前的Runable接口:
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
区别:这两个方法很相似,两者都是函数式接口(只有一个不包含方法体的方法的接口),但是区别也很明显:
1、Callable接口有返回值
2、Callable接口的call方法抛出了异常,而Runable没有
Future与FutureTask
Callable返回的值被保存在Future中,使用 Future 我们可以得知 Callable 的运行状态,
以及获取 Callable 执行完后的返回值。
Future<String> future = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "OK";
}
});
Future有几个方法,说明如下:
/**
* 获取异步执行结果,注意:这个方法的调用会被阻塞直到方法运行完成
*/
String result = future.get();
/**
* 获取异步结果,指定一个时间,若该时间内Call方法仍然没有返回结果,则抛出TimeoutException
*/
try {
String result_wait = future.get(1, TimeUnit.SECONDS);
} catch (TimeoutException e) {
e.printStackTrace();
}
/**
* 取消call方法运行,如果还没开始,就直接取消;如果已经在运行了,其bollean参数表示是否被中断,
* true就是被中断
*/
future.cancel(true);
/**
* 已经完成Call方法返回true,否则false
*/
boolean done = future.isDone();
FutureTask包装器是一种非常便利的机制,可将Callable转换成Future和Runable,它实现了RunableFuture这个接口,将Future和Runable结合在一起。这样我们就也可以使用Callable来创建Thread了。
*
* @since 1.5
* @author Doug Lea
* @param <V> The result type returned by this FutureTask's {@code get} methods
*/
public class FutureTask<V> implements RunnableFuture<V>
/**
*RunableFuture接口
*/
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
FutureTask使用:
FutureTask<String> futureTask = new FutureTask<String>(() -> {
return "fsd";
});
new Thread(futureTask).start();
futureTask.get();
futureTask.cancel(true);
futureTask.isDone();
网友评论