1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.concurrency.Executor;
13 
14 import hunt.Exceptions;
15 
16 /**
17  * An object that executes submitted {@link Runnable} tasks. This
18  * interface provides a way of decoupling task submission from the
19  * mechanics of how each task will be run, including details of thread
20  * use, scheduling, etc.  An {@code Executor} is normally used
21  * instead of explicitly creating threads. For example, rather than
22  * invoking {@code new Thread(new RunnableTask()).start()} for each
23  * of a set of tasks, you might use:
24  *
25  * <pre> {@code
26  * Executor executor = anExecutor();
27  * executor.execute(new RunnableTask1());
28  * executor.execute(new RunnableTask2());
29  * ...}</pre>
30  *
31  * However, the {@code Executor} interface does not strictly require
32  * that execution be asynchronous. In the simplest case, an executor
33  * can run the submitted task immediately in the caller's thread:
34  *
35  * <pre> {@code
36  * class DirectExecutor implements Executor {
37  *   public void execute(Runnable r) {
38  *     r.run();
39  *   }
40  * }}</pre>
41  *
42  * More typically, tasks are executed in some thread other than the
43  * caller's thread.  The executor below spawns a new thread for each
44  * task.
45  *
46  * <pre> {@code
47  * class ThreadPerTaskExecutor implements Executor {
48  *   public void execute(Runnable r) {
49  *     new Thread(r).start();
50  *   }
51  * }}</pre>
52  *
53  * Many {@code Executor} implementations impose some sort of
54  * limitation on how and when tasks are scheduled.  The executor below
55  * serializes the submission of tasks to a second executor,
56  * illustrating a composite executor.
57  *
58  * <pre> {@code
59  * class SerialExecutor implements Executor {
60  *   final Queue!(Runnable) tasks = new ArrayDeque<>();
61  *   final Executor executor;
62  *   Runnable active;
63  *
64  *   SerialExecutor(Executor executor) {
65  *     this.executor = executor;
66  *   }
67  *
68  *   public synchronized void execute(Runnable r) {
69  *     tasks.add(() -> {
70  *       try {
71  *         r.run();
72  *       } finally {
73  *         scheduleNext();
74  *       }
75  *     });
76  *     if (active is null) {
77  *       scheduleNext();
78  *     }
79  *   }
80  *
81  *   protected synchronized void scheduleNext() {
82  *     if ((active = tasks.poll()) !is null) {
83  *       executor.execute(active);
84  *     }
85  *   }
86  * }}</pre>
87  *
88  * The {@code Executor} implementations provided in this package
89  * implement {@link ExecutorService}, which is a more extensive
90  * interface.  The {@link ThreadPoolExecutor} class provides an
91  * extensible thread pool implementation. The {@link Executors} class
92  * provides convenient factory methods for these Executors.
93  *
94  * <p>Memory consistency effects: Actions in a thread prior to
95  * submitting a {@code Runnable} object to an {@code Executor}
96  * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
97  * its execution begins, perhaps in another thread.
98  *
99  * @since 1.5
100  * @author Doug Lea
101  */
102 // interface Executor {
103 
104 //     /**
105 //      * Executes the given command at some time in the future.  The command
106 //      * may execute in a new thread, in a pooled thread, or in the calling
107 //      * thread, at the discretion of the {@code Executor} implementation.
108 //      *
109 //      * @param command the runnable task
110 //      * @throws RejectedExecutionException if this task cannot be
111 //      * accepted for execution
112 //      * @throws NullPointerException if command is null
113 //      */
114 //     void execute(Runnable command);
115 // }