简介:
这两个接口都可以代表一个任务,可以被多线程执行。Runnable可以同时被Thread和ExecutorService执行,而Callable只可以被ExecutorService执行。Callable支持泛型。
源码分析:
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface Runnable
is used
* to create a thread, starting the thread causes the object's
* run
method to be called in that separately executing
* thread.
*
* The general contract of the method run
is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
run方法没有返回值,没有抛出可检查异常。
@FunctionalInterface
public interface Callable {
/**
* 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方法有通用返回值,并且方法签名上面抛出Exception。
Callable被ExecutorService执行的简单流程介绍:
ExecutorService方法声明:
/**
* An {@link Executor} that provides methods to manage termination and
* methods that can produce a {@link Future} for tracking progress of
* one or more asynchronous tasks.
**/
Future submit(Callable task);
AbstractExecutorService实现ExecutorService接口:
public Future submit(Callable task) {
if (task == null) throw new NullPointerException();
RunnableFuture ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
把Callable封装在FutureTask类里面
protected RunnableFuture newTaskFor(Callable callable) {
return new FutureTask(callable);
}
public FutureTask(Callable callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
FutureTask实现了RunnableFuture接口,RunnableFuture接口继承了Runnable, Future
/**
* A cancellable asynchronous computation. This class provides a base
* implementation of {@link Future}, with methods to start and cancel
* a computation, query to see if the computation is complete, and
* retrieve the result of the computation. The result can only be
* retrieved when the computation has completed; the {@code get}
* methods will block if the computation has not yet completed. Once
* the computation has completed, the computation cannot be restarted
* or cancelled (unless the computation is invoked using
* {@link #runAndReset}).
*
* A {@code FutureTask} can be used to wrap a {@link Callable} or
* {@link Runnable} object. Because {@code FutureTask} implements
* {@code Runnable}, a {@code FutureTask} can be submitted to an
* {@link Executor} for execution.
**/
封装完之后,执行execute(ftask)这个方法,具体实现在ThreadPoolExecutor里面,代码如下:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
执行代码在addWorker里面,这个方法有点复杂,这次主要是为了记录Callable被执行的大致流程,所以具体每一行代码的含义留给以后再好好的分析、学习。其实,最终调用的还是FutureTask的run方法,如下图,这个run方法里面又调用了Callable的call方法。
public void run() {
if (state != NEW ||
!RUNNER.compareAndSet(this, null, Thread.currentThread()))
return;
try {
Callable c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
场景:
1、异步执行任务。
2、跟踪异步执行任务的结果。
随便聊聊:
虽然分析的不够深入,并没有把每一行代码的含义都说清楚(这还是要花很多时间和精力一点点去啃的),但是已初步能看出来Callable接口是如何被执行的,其实还是依赖Runnable,然后在对应的run方法里面再显式调用call方法,只不过这中间经历了好多特意设计流程,这些设计流程,也体现出了,jdk源码的复杂和可值得学习的地方。