前言
- 执行已提交的{@link Runnable}任务的对象。
- 该接口提供了一种将任务提交与每个任务将如何运行的机制(包括线程使用,调度的详细信息)的机制脱钩的方法。
- 通常使用{@code Executor}而不是显式创建线程。
- 例如,可以为每个任务集调用{@code new Thread(new(RunnableTask())。start()},而不是使用:
- Executor executor = anExecutor;
- executor.execute(new RunnableTask1());
- executor.execute(new RunnableTask2());
- 但是,{@code 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();
- }
- }}
- 许多{@code Executor}实现对计划任务的方式和时间施加了某种限制。
- 下面的执行程序将任务提交序列化到第二个执行程序,说明了一个复合执行程序。
- class SerialExecutor implements Executor {
- final Queue tasks = new ArrayDeque();
- 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);
-
}
- }
- }}
- 此程序包中提供的{@code Executor}实现实现{@link ExecutorService},这是一个更广泛的接口。
- {@link ThreadPoolExecutor}类提供了可扩展的线程池实现。
- {@link Executors}类为这些Executor提供了方便的工厂方法。
- 内存一致性影响:
- 在将{@code Runnable}对象提交给{@code Executor}发生之前,在线程中执行的操作-可能在另一个线程执行之前。
源码
package java.util.concurrent;
public interface Executor {
/**
* Executes the given command at some time in the future. The command
* may execute in a new thread, in a pooled thread, or in the calling
* thread, at the discretion of the {@code Executor} implementation.
*
* 在将来的某个时间执行给定的命令。根据{@code Executor}实现的判断,命令可以在新线程中,在合并线程中或在调用线程中执行。
*
* @param command the runnable task
* @throws RejectedExecutionException if this task cannot be
* accepted for execution
* @throws NullPointerException if command is null
*/
void execute(Runnable command);
}