一.Runnable, Callable, FutureTask简介
- Runnable:我们需要实现run()方法,然后放入Thread中运行,无返回值。
- Callable:实现T call()方法,由ExecutorService.submit()放入线程池中运行,具有返回值。
- FutureTask:所有由ExecutorService.submit()放入线程池中的任务,不管是Runnable或者是Callable最后都封装成一个FutureTask,并且返回,我们可以通过返回的FutureTask对线程进行控制,比如获得结果,取消执行,判断是否执行完成。
二.Runnable
这个接口只有一个run方法,当我们想执行一个任务,最简单方法就是实现一个Runnable接口,将它放入Thread中执行就可以了。
例:
static public void main(String args[]){
runnableTest();
}
/**
* 线程执行中
*/
static public void runnableTest(){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程执行中");
}
});
thread.run();
} 这个就是一个很简单的线程执行示例,我们可以通过这个方法做些异步的操作。这样是有局限性的,如果我们需要查看执行结果,只能另外的写代码去查看执行的结果。二.Callable
Callable是一个可以执行有返回值的任务,这也是他和Runnable的区别
例:
static public void useFutureTaskWithCallable(){
ExecutorService executorService = Executors.newFixedThreadPool(4);
Future<?> future = executorService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
return "ttttt";
}
});
try {
showMessage(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
}Callable不支持直接放入Thread中运行。它可以直接通过submit提交给线程池,最后运行,通过返回的Future.get()取得结果。那么Future是什么呢?
三.Future
Future是用于对线程控制的接口,当我们用线程池的Submit方法提交一个任务时候,就会返回一个可以对线程操控的Future对象。Future有方法呢?
- boolean cancel(boolean mayInterruptIfRunning) 取消线程的执行mayInterruptIfRunning值为true时,这个线程会调用interrupt,线程可能会中断。为false时这个线程不会调用interrupt。
- V get()调用方法的线程会阻塞直到任务执行完成,获得返回值
- V get(long timeout, TimeUnit unit)设定获取结果线程最长阻塞时间,如果在这个时间呢还没有返回结果,会抛出一个TimeoutException异常
- boolean isCancelled()判断线程是否被取消执行
- boolean isDone()判断线程是否执行完成
二.FutureTask
FutureTask是Future的实现类,也就是说只有通过这个类我们才能对线程实现控制。所有放入线程池中的任务不管是Runnable,Callable都会被封装成一个FutureTask,FutureTask也提供了通过Runnable和Callable构造一个FutureTask的方法。
- FutureTask(Runnable runnable, V result)
- FutureTask(Callable<V> callable)
四.关于继承
FutureTask 实现的是RunnableFuture接口.
public class FutureTask<V> implements RunnableFuture<V>RunnableFuture接口继承的是Runnable,Future接口public interface RunnableFuture<V> extends Runnable, Future<V>
也就是说FutureTask具有run方法和线程控制的那些方法。那么Callable呢?Callable没有继承任何的接口,它只有一个run方法
public interface Callable<V> {
V call() throws Exception;
}在FutureTask中,每个传入的Runnable都被封装成一个Callable对象,中间通过适配器模式RunnableAdapter,将不同的接口组装成一相同的call方法。然后FutureTask的run方法中去调用自己的Callable对象。
好嘛。run变成call再变成run。变一次之后就具有返回值功能了。
值得一提,线程池的submit封装成的FutureTask,最后执行任务的时候就是调用Thread去执行的,也就是说执行的是run方法。
所以说所有的都是异端,除了Runnable。
本文介绍了Java中的Runnable、Callable接口以及FutureTask的使用。Runnable用于无返回值的任务,而Callable可以返回结果。FutureTask是ExecutorService提交任务时的封装,提供了取消任务、获取结果、判断任务状态等方法。
614

被折叠的 条评论
为什么被折叠?



