① Runnable
它是一个接口,在它里面只声明了一个run()方法:
public interface Runnable {
public abstract void run();
}
由于run()方法返回值为void类型,所以在执行完任务之后无法返回任何结果。
使用:实现Runnable接口,重写run()方法。
class RunnableImpl implements Runnable
作为创建线程的参数:Thread thread = new Thread (Runnable RunnbaleImpl);
作为要执行的任务提交到线程池:threadPool.submit (Runnable RunnableImpl);
或者是threadPool.execute (Runnable RunnableImpl);
② Callable
是一个接口,在它里面也只声明了一个方法,只不过这个方法叫做call():
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;
}
call()方法返回泛型V,所以提交Callable接口返回Future接口类,并且会抛出异常。
使用:
A. 定义MyClass实现Callable接口;
class CallabImpl implements Callable
B. 重写call(),将执行的代码写入;
C. 将CallableImpl包装成FutureTask对象;
FutureTask实现了Runnable和Future接口,可以当作Runnable接口耐心hi用。FutureTask通过在run()内部调用call()来执行任务,并保存了call()的返回值;
FutureTask runnable = new FutureTask(new CallableImpl ());
D. 创建Thread的对象,也可以提交到线程池执行;
Thread thread = new Thread(runnable);//传入参数Runnable接口
threadPool.submit(runnable);//execute()也可以
E. 此外Callable对象也可以单独提交到线程池执行;
Future submit(Callable task);
③ Runnable和Callable运用:配合线程池使用
Future submit(Callable task);//多
Future submit(Runnable task, T result);//少
Future<?> submit(Runnable task);//execute()方法也行,只是没有返回值.
不管是Runnable还是Callable,在提交任务至线程池的过程中会被包装成RunnableFuture供内部execute()使用。
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
④ Future
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。
比如向线程池提交任务,返回Future.
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
Future类位于java.util.concurrent包下,它是一个接口:
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;
}
1) cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。
① 如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;
② 如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;
③ 如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
2) isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
3) isDone方法表示任务是否已经完成,若任务完成,则返回true;
4) get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
5) get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
总结:Future提供了三种功能:
1)判断任务是否完成;
2)能够中断任务;
3)能够获取任务执行结果。
⑤ FutureTask:实现了Runnable和Future接口(后者的唯一实现类)
Future只是一个接口,所以是无法直接用来创建对象使用的,一般是采用它的唯一实现类FutureTask。
public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V> {
void run();
}
可以看出FutureTask实现了RunnableFuture接口,而RunnableFuture继承了Runnable接口和Future接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。