001 /**
002 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
003 * Copyright (C) 2012 FuseSource, Inc.
004 * http://fusesource.com
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package org.fusesource.hawtdispatch;
020
021 import java.util.concurrent.Executor;
022 import java.util.concurrent.TimeUnit;
023
024 /**
025 *
026 * <p>
027 * Dispatch queues are lightweight objects to which runnable objects
028 * may be submitted for asynchronous execution and therefore are
029 * {@link Executor} objects.
030 * </p>
031 *
032 *
033 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
034 */
035 public interface DispatchQueue extends DispatchObject, Executor {
036
037 /**
038 * Defines the types of dispatch queues supported by the system.
039 */
040 enum QueueType {
041
042 /**
043 * A global queue represents a dispatch queue which executes
044 * runnable objects in a concurrently.
045 */
046 GLOBAL_QUEUE,
047
048 /**
049 * A serial dispatch queues executes runnable objects
050 * submitted to them serially in FIFO order. A
051 * queue will only invoke one runnable at a time,
052 * ut independent queues may each invoke their runnables
053 * concurrently with respect to each other.
054 */
055 SERIAL_QUEUE,
056
057 /**
058 * A thread queue is a dispatch queue associated with a specific
059 * thread. It executes runnable objects submitted to them
060 * serially in FIFO order.
061 */
062 THREAD_QUEUE
063 }
064
065 /**
066 * @return the type of dispatch queue that this object implements.
067 */
068 public QueueType getQueueType();
069
070 /**
071 * <p>
072 * Creates a new serial dispatch queue with this queue set as it's
073 * target queue. See {@link Dispatch#createQueue(String)} for
074 * more information about serial dispatch queues.
075 * </p>
076 *
077 * @param label the label to assign the dispatch queue, can be null
078 * @return the newly created dispatch queue
079 */
080 public DispatchQueue createQueue(String label);
081
082 /**
083 * <p>
084 * Submits a runnable for asynchronous execution on a dispatch queue.
085 * </p><p>
086 * {@link #execute(Runnable)} is the fundamental mechanism for submitting
087 * runnable objects to a dispatch queue.
088 * </p><p>
089 * Calls to {@link #execute(Runnable)} always return immediately after the runnable has
090 * been submitted, and never wait for the runnable to be executed.
091 * </p><p>
092 * The target queue determines whether the runnable will be invoked serially or
093 * concurrently with respect to other runnables submitted to that same queue.
094 * Serial queues are processed concurrently with with respect to each other.
095 * </p>
096 *
097 * @param runnable
098 * The runnable to submit to the dispatch queue.
099 */
100 void execute(Runnable runnable);
101
102 /**
103 * <p>
104 * Submits a task for asynchronous execution on a dispatch queue.
105 * </p><p>
106 * {@link #execute(Task)} is the fundamental mechanism for submitting
107 * runnable objects to a dispatch queue.
108 * </p><p>
109 * Calls to {@link #execute(Task)} always return immediately after the runnable has
110 * been submitted, and never wait for the runnable to be executed.
111 * </p><p>
112 * The target queue determines whether the runnable will be invoked serially or
113 * concurrently with respect to other runnables submitted to that same queue.
114 * Serial queues are processed concurrently with with respect to each other.
115 * </p>
116 *
117 * @param task
118 * The task to submit to the dispatch queue.
119 */
120 void execute(Task task);
121
122 /**
123 * <p>
124 * Schedule a runnable for execution on a given queue at a specified time.
125 * </p>
126 *
127 * @param delay
128 * the amount of time to delay before executing the runnable
129 * @param unit the unit of time that the delay value is specified in
130 * @param runnable
131 */
132 public void executeAfter(long delay, TimeUnit unit, Runnable runnable);
133
134 /**
135 * <p>
136 * Schedule a task for execution on a given queue at a specified time.
137 * </p>
138 *
139 * @param delay
140 * the amount of time to delay before executing the runnable
141 * @param unit the unit of time that the delay value is specified in
142 * @param task
143 */
144 public void executeAfter(long delay, TimeUnit unit, Task task);
145
146 //
147 // This is an API method that libdispatch supports, but even they don't recommend it's
148 // use. Due to the static nature of our thread pool implementation it's even more dangerous.
149 // so leaving it commented out for now so that folks don't use it. Perhaps we can enable it
150 // in a future release.
151 //
152 // /**
153 // * <p>
154 // * Submits a runnable for synchronous execution on a dispatch queue.
155 // * </p><p>
156 // * Submits a runnable to a dispatch queue like dispatch_async(), however
157 // * {@link #dispatchSync(Runnable)} will not return until the runnable
158 // * has finished.
159 // * </p><p>
160 // * Calls to {@link #dispatchSync(Runnable)} targeting the current queue will result
161 // * in dead-lock. Use of {@link #dispatchSync(Runnable)} is also subject to the same
162 // * multi-party dead-lock problems that may result from the use of a mutex.
163 // * Use of {@link #execute(Runnable)} is preferred.
164 // * </p>
165 // *
166 // * @param runnable
167 // * The runnable to be invoked on the target dispatch queue.
168 // */
169 // public void dispatchSync(Runnable runnable) throws InterruptedException;
170
171 // Ditto..
172 //
173 // /**
174 // * <p>
175 // * Submits a runnable to a dispatch queue for multiple invocations.
176 // * </p><p>
177 // * This function
178 // * waits for the task runnable to complete before returning. If the target queue
179 // * is a concurrent queue returned by {@link Dispatch#getGlobalQueue()}, the runnable
180 // * may be invoked concurrently, and it must therefore be thread safe.
181 // * </p>
182 // *
183 // * @param iterations
184 // * The number of iterations to perform.
185 // * <br/>
186 // * @param runnable
187 // * The runnable to be invoked the specified number of iterations.
188 // */
189 // public void dispatchApply(int iterations, Runnable runnable) throws InterruptedException;
190
191 /**
192 * <p>
193 * Returns the label of the queue.
194 * </p>
195 *
196 * @return the label of the queue. The result may be null.
197 */
198 public String getLabel();
199
200 /**
201 * <p>
202 * Sets the label of the queue.
203 * </p>
204 *
205 * @param label the label of the queue.
206 */
207 public void setLabel(String label);
208
209 /**
210 * <p>
211 * Returns true if this dispatch queue is executing the caller.
212 * </p>
213 *
214 * @return if this dispatch queue is executing the caller.
215 */
216 public boolean isExecuting();
217
218 /**
219 * Asserts that the current dispatch queue is executing.
220 */
221 public void assertExecuting();
222
223 /**
224 * Enables or disables profiler metric tracking on the queue.
225 * @param on
226 */
227 void profile(boolean on);
228
229 /**
230 * Returns the usage metrics of this queue. Only returns a value
231 * if the queue has profiling enabled.
232 *
233 * @return new metric counters accumulated since last called or null if the queue has not been used.
234 */
235 Metrics metrics();
236
237 }