本文按:
1. Callable 与Runnable的使用
2. Callable 与Runnable的区别
3. Future的使用
4. FutureTask的使用
1. Callable 与Runnable的使用
Callable经常与ExecutorService配合使用,用于提交带有返回值的任务; Runnable可以与thread pool配合使用也可以单独使用。具体的使用方法如下:
public class RunnableAndCallable {
static ExecutorService executor = Executors.newCachedThreadPool();
public static void main(String[] args) {
//Runnable
executor.execute(new RunnableTask());
executor.submit(new RunnableTask());
//Callable & Future
Future<String> future = executor.submit(new CallableTask());
try {
System.out.println((String) future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//FutureTask & Callable
FutureTask<String> futureTask = new FutureTask<String>(new CallableTask());
try {
//任务执行
futureTask.run();
String s = (String)futureTask.get();
System.out.println("FutureTask " + s);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//否则线程不会退出
executor.shutdown();
}
}
//返回参数为空
//使用execute() 提交任务
class RunnableTask implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " start runnable");
}
}
//是一个泛型接口,具有返回参数
//使用submit() 提交任务
class CallableTask implements Callable<String>{
@Override
public String call() throws Exception {
return "here is callable test";
}
}
2. Callable 与Runnable的区别
(1)Runnable 接口是自java 1.0就有的, Callable接口是java1.5以后加入的特性
(2)Callable 接口使用call()方法执行task;Runnable接口使用run()执行task
(3)run()方法没有返回值,Callable接口是一个泛型参数接口,具有返回值
(4)Callable定义的Task只能用submit() 方法添加到任务队列; Runnable定义的接口既可以使用submit()也可以使用execute()提交到任务队列
(5)如果使用invokeAll()一次提交多个任务只能使用Callable实现的任务
3. Future的使用
Future接口的代码如下:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
- cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
- isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
- isDone方法表示任务是否已经完成,若任务完成,则返回true;
- get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
- get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
也就是说Future提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。
4. FutureTask 的使用
FutureTask类:
public class FutureTask<V> implements RunnableFuture<V>
RunnableFuture 接口:
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。
参考:http://www.cnblogs.com/dolphin0520/p/3949310.html