001: /*
002: * Written by Doug Lea with assistance from members of JCP JSR-166
003: * Expert Group and released to the public domain, as explained at
004: * http://creativecommons.org/licenses/publicdomain
005: */
006:
007: package java.util.concurrent;
008:
009: /**
010: * An object that executes submitted {@link Runnable} tasks. This
011: * interface provides a way of decoupling task submission from the
012: * mechanics of how each task will be run, including details of thread
013: * use, scheduling, etc. An <tt>Executor</tt> is normally used
014: * instead of explicitly creating threads. For example, rather than
015: * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each
016: * of a set of tasks, you might use:
017: *
018: * <pre>
019: * Executor executor = <em>anExecutor</em>;
020: * executor.execute(new RunnableTask1());
021: * executor.execute(new RunnableTask2());
022: * ...
023: * </pre>
024: *
025: * However, the <tt>Executor</tt> interface does not strictly
026: * require that execution be asynchronous. In the simplest case, an
027: * executor can run the submitted task immediately in the caller's
028: * thread:
029: *
030: * <pre>
031: * class DirectExecutor implements Executor {
032: * public void execute(Runnable r) {
033: * r.run();
034: * }
035: * }</pre>
036: *
037: * More typically, tasks are executed in some thread other
038: * than the caller's thread. The executor below spawns a new thread
039: * for each task.
040: *
041: * <pre>
042: * class ThreadPerTaskExecutor implements Executor {
043: * public void execute(Runnable r) {
044: * new Thread(r).start();
045: * }
046: * }</pre>
047: *
048: * Many <tt>Executor</tt> implementations impose some sort of
049: * limitation on how and when tasks are scheduled. The executor below
050: * serializes the submission of tasks to a second executor,
051: * illustrating a composite executor.
052: *
053: * <pre>
054: * class SerialExecutor implements Executor {
055: * final Queue<Runnable> tasks = new LinkedBlockingQueue<Runnable>();
056: * final Executor executor;
057: * Runnable active;
058: *
059: * SerialExecutor(Executor executor) {
060: * this.executor = executor;
061: * }
062: *
063: * public synchronized void execute(final Runnable r) {
064: * tasks.offer(new Runnable() {
065: * public void run() {
066: * try {
067: * r.run();
068: * } finally {
069: * scheduleNext();
070: * }
071: * }
072: * });
073: * if (active == null) {
074: * scheduleNext();
075: * }
076: * }
077: *
078: * protected synchronized void scheduleNext() {
079: * if ((active = tasks.poll()) != null) {
080: * executor.execute(active);
081: * }
082: * }
083: * }</pre>
084: *
085: * The <tt>Executor</tt> implementations provided in this package
086: * implement {@link ExecutorService}, which is a more extensive
087: * interface. The {@link ThreadPoolExecutor} class provides an
088: * extensible thread pool implementation. The {@link Executors} class
089: * provides convenient factory methods for these Executors.
090: *
091: * @since 1.5
092: * @author Doug Lea
093: */
094: public interface Executor {
095:
096: /**
097: * Executes the given command at some time in the future. The command
098: * may execute in a new thread, in a pooled thread, or in the calling
099: * thread, at the discretion of the <tt>Executor</tt> implementation.
100: *
101: * @param command the runnable task
102: * @throws RejectedExecutionException if this task cannot be
103: * accepted for execution.
104: * @throws NullPointerException if command is null
105: */
106: void execute(Runnable command);
107: }
|