package java.util.concurrent;
/**
* 执行已提交的Runnable任务的对象。
* 这个接口提供了一种将任务提交与每个任务如何运行的机制(包括线程使用、调度等细节)分离的方法。
* 通常使用Executor而不是显式地创建线程。
* 例如,与其对一组任务调用new Thread(new(RunnableTask())).start(),不如使用:
*
* <pre>
* Executor executor = <em>anExecutor</em>;
* executor.execute(new RunnableTask1());
* executor.execute(new RunnableTask2());
* ...
* </pre>
*
* 然而,Executor接口并不严格要求执行是异步的。
* 在最简单的情况下,Executor可以在调用者的线程中立即运行提交的任务:
*
* <pre> {@code
* class DirectExecutor implements Executor {
* public void execute(Runnable r) {
* r.run();
* }
* }}</pre>
*
* 更典型的是,任务在某个线程中执行,而不是在调用者的线程中执行。
* 下面的执行程序为每个任务生成一个新的线程。
*
* <pre> {@code
* class ThreadPerTaskExecutor implements Executor {
* public void execute(Runnable r) {
* new Thread(r).start();
* }
* }}</pre>
*
* 许多执行器实现对任务的调度方式和时间施加了某种限制。
* 下面的执行程序序列化向第二个执行程序提交任务,说明复合执行程序。
*
* <pre> {@code
* 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);
* }
* }
* }}</pre>
*
* 这个包中提供的执行器实现实现了ExecutorService,这是一个更广泛的接口。
* ThreadPoolExecutor类提供了一个可扩展的线程池实现。
* Executors类为这些executor提供了方便的工厂方法。
*
* <p>内存一致性效应:在一个线程中,在将一个可运行对象提交给一个执行程序之前,
* happen-before 在它开始执行之前,可能在另一个线程中。
*
* @since 1.5
* @author Doug Lea
*/
public interface 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);
}