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 019package org.fusesource.hawtdispatch; 020 021import java.util.concurrent.Executor; 022import 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 */ 035public 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 * @return true is profiling is enabled. 231 */ 232 boolean profile(); 233 234 /** 235 * Returns the usage metrics of this queue. Only returns a value 236 * if the queue has profiling enabled. 237 * 238 * @return new metric counters accumulated since last called or null if the queue has not been used. 239 */ 240 Metrics metrics(); 241 242}