执行提交的可运行任务的对象。该接口提供了一种将任务提交与如何运行每个任务的机制解耦的方式,包括线程使用的详细信息等。通常使用 Executor 代替显式创建线程。例如,您可以使用以下命令来代替为每个任务集调用 new Thread(new(RunnableTask()).start():
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
但是,Executor接口并不严格要求执行是异步的。在最简单的情况下,执行者可以在调用者的线程中立即运行提交的任务:
class DirectExecutor implements Executor {
public void execute(Runnable r) {
r.run();
}
}
更典型地,任务在调用者线程之外的某个线程中执行。下面的执行程序为每个任务生成一个新线程。
class ThreadPerTaskExecutor implements Executor {
public void execute(Runnable r) {
new Thread(r).start();
}
}
许多实现类对计划任务的方式和时间施加了某种限制。下面的执行程序将任务提交序列化到第二个执行程序,组成了一个组合执行器。
class SerialExecutor implements Executor {
final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
final Executor executor;
Runnable active;
SerialExecutor(Executor executor) {
this.executor = executor;
}
public synchronized void execute(final Runnable r) {
tasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (active == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((active = tasks.poll()) != null) {
executor.execute(active);
}
}
}
此程序包中提供的Executor实现类实现了 ExecutorService,这是一个更广泛的接口。ThreadPoolExecutor 类提供了可扩展的线程池实现。Executors 类为这些 Executor 提供了方便的工厂方法。
这里有一个 happen-before 保证:线程中将Runnable对象提交给Executor的操作发生在执行器执行前,也许是在另一个线程中。
根据执行程序的执行情况,命令可以在新线程,池线程或调用线程中执行。
Executor 在 juc 中的类图:

Executor 类图
接下来我们就看下 ExecutorService;