1 /* 2 * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.nio.channels; 27 28 import java.nio.channels.spi.AsynchronousChannelProvider; 29 import java.io.IOException; 30 import java.util.concurrent.ExecutorService; 31 import java.util.concurrent.ThreadFactory; 32 import java.util.concurrent.TimeUnit; 33 34 /** 35 * A grouping of asynchronous channels for the purpose of resource sharing. 36 * 37 * <p> An asynchronous channel group encapsulates the mechanics required to 38 * handle the completion of I/O operations initiated by {@link AsynchronousChannel 39 * asynchronous channels} that are bound to the group. A group has an associated 40 * thread pool to which tasks are submitted to handle I/O events and dispatch to 41 * {@link CompletionHandler completion-handlers} that consume the result of 42 * asynchronous operations performed on channels in the group. In addition to 43 * handling I/O events, the pooled threads may also execute other tasks required 44 * to support the execution of asynchronous I/O operations. 45 * 46 * <p> An asynchronous channel group is created by invoking the {@link 47 * #withFixedThreadPool withFixedThreadPool} or {@link #withCachedThreadPool 48 * withCachedThreadPool} methods defined here. Channels are bound to a group by 49 * specifying the group when constructing the channel. The associated thread 50 * pool is <em>owned</em> by the group; termination of the group results in the 51 * shutdown of the associated thread pool. 52 * 53 * <p> In addition to groups created explicitly, the Java virtual machine 54 * maintains a system-wide <em>default group</em> that is constructed 55 * automatically. Asynchronous channels that do not specify a group at 56 * construction time are bound to the default group. The default group has an 57 * associated thread pool that creates new threads as needed. The default group 58 * may be configured by means of system properties defined in the table below. 59 * Where the {@link java.util.concurrent.ThreadFactory ThreadFactory} for the 60 * default group is not configured then the pooled threads of the default group 61 * are {@link Thread#isDaemon daemon} threads. 62 * 63 * <table border summary="System properties"> 64 * <tr> 65 * <th>System property</th> 66 * <th>Description</th> 67 * </tr> 68 * <tr> 69 * <td> {@code java.nio.channels.DefaultThreadPool.threadFactory} </td> 70 * <td> The value of this property is taken to be the fully-qualified name 71 * of a concrete {@link java.util.concurrent.ThreadFactory ThreadFactory} 72 * class. The class is loaded using the system class loader and instantiated. 73 * The factory's {@link java.util.concurrent.ThreadFactory#newThread 74 * newThread} method is invoked to create each thread for the default 75 * group's thread pool. If the process to load and instantiate the value 76 * of the property fails then an unspecified error is thrown during the 77 * construction of the default group. </td> 78 * </tr> 79 * <tr> 80 * <td> {@code java.nio.channels.DefaultThreadPool.initialSize} </td> 81 * <td> The value of the {@code initialSize} parameter for the default 82 * group (see {@link #withCachedThreadPool withCachedThreadPool}). 83 * The value of the property is taken to be the {@code String} 84 * representation of an {@code Integer} that is the initial size parameter. 85 * If the value cannot be parsed as an {@code Integer} it causes an 86 * unspecified error to be thrown during the construction of the default 87 * group. </td> 88 * </tr> 89 * </table> 90 * 91 * <a name="threading"></a><h2>Threading</h2> 92 * 93 * <p> The completion handler for an I/O operation initiated on a channel bound 94 * to a group is guaranteed to be invoked by one of the pooled threads in the 95 * group. This ensures that the completion handler is run by a thread with the 96 * expected <em>identity</em>. 97 * 98 * <p> Where an I/O operation completes immediately, and the initiating thread 99 * is one of the pooled threads in the group then the completion handler may 100 * be invoked directly by the initiating thread. To avoid stack overflow, an 101 * implementation may impose a limit as to the number of activations on the 102 * thread stack. Some I/O operations may prohibit invoking the completion 103 * handler directly by the initiating thread (see {@link 104 * AsynchronousServerSocketChannel#accept(Object,CompletionHandler) accept}). 105 * 106 * <a name="shutdown"></a><h2>Shutdown and Termination</h2> 107 * 108 * <p> The {@link #shutdown() shutdown} method is used to initiate an <em>orderly 109 * shutdown</em> of a group. An orderly shutdown marks the group as shutdown; 110 * further attempts to construct a channel that binds to the group will throw 111 * {@link ShutdownChannelGroupException}. Whether or not a group is shutdown can 112 * be tested using the {@link #isShutdown() isShutdown} method. Once shutdown, 113 * the group <em>terminates</em> when all asynchronous channels that are bound to 114 * the group are closed, all actively executing completion handlers have run to 115 * completion, and resources used by the group are released. No attempt is made 116 * to stop or interrupt threads that are executing completion handlers. The 117 * {@link #isTerminated() isTerminated} method is used to test if the group has 118 * terminated, and the {@link #awaitTermination awaitTermination} method can be 119 * used to block until the group has terminated. 120 * 121 * <p> The {@link #shutdownNow() shutdownNow} method can be used to initiate a 122 * <em>forceful shutdown</em> of the group. In addition to the actions performed 123 * by an orderly shutdown, the {@code shutdownNow} method closes all open channels 124 * in the group as if by invoking the {@link AsynchronousChannel#close close} 125 * method. 126 * 127 * @since 1.7 128 * 129 * @see AsynchronousSocketChannel#open(AsynchronousChannelGroup) 130 * @see AsynchronousServerSocketChannel#open(AsynchronousChannelGroup) 131 */ 132 133 public abstract class AsynchronousChannelGroup { 134 private final AsynchronousChannelProvider provider; 135 136 /** 137 * Initialize a new instance of this class. 138 * 139 * @param provider 140 * The asynchronous channel provider for this group 141 */ AsynchronousChannelGroup(AsynchronousChannelProvider provider)142 protected AsynchronousChannelGroup(AsynchronousChannelProvider provider) { 143 this.provider = provider; 144 } 145 146 /** 147 * Returns the provider that created this channel group. 148 * 149 * @return The provider that created this channel group 150 */ provider()151 public final AsynchronousChannelProvider provider() { 152 return provider; 153 } 154 155 /** 156 * Creates an asynchronous channel group with a fixed thread pool. 157 * 158 * <p> The resulting asynchronous channel group reuses a fixed number of 159 * threads. At any point, at most {@code nThreads} threads will be active 160 * processing tasks that are submitted to handle I/O events and dispatch 161 * completion results for operations initiated on asynchronous channels in 162 * the group. 163 * 164 * <p> The group is created by invoking the {@link 165 * AsynchronousChannelProvider#openAsynchronousChannelGroup(int,ThreadFactory) 166 * openAsynchronousChannelGroup(int,ThreadFactory)} method of the system-wide 167 * default {@link AsynchronousChannelProvider} object. 168 * 169 * @param nThreads 170 * The number of threads in the pool 171 * @param threadFactory 172 * The factory to use when creating new threads 173 * 174 * @return A new asynchronous channel group 175 * 176 * @throws IllegalArgumentException 177 * If {@code nThreads <= 0} 178 * @throws IOException 179 * If an I/O error occurs 180 */ withFixedThreadPool(int nThreads, ThreadFactory threadFactory)181 public static AsynchronousChannelGroup withFixedThreadPool(int nThreads, 182 ThreadFactory threadFactory) 183 throws IOException 184 { 185 return AsynchronousChannelProvider.provider() 186 .openAsynchronousChannelGroup(nThreads, threadFactory); 187 } 188 189 /** 190 * Creates an asynchronous channel group with a given thread pool that 191 * creates new threads as needed. 192 * 193 * <p> The {@code executor} parameter is an {@code ExecutorService} that 194 * creates new threads as needed to execute tasks that are submitted to 195 * handle I/O events and dispatch completion results for operations initiated 196 * on asynchronous channels in the group. It may reuse previously constructed 197 * threads when they are available. 198 * 199 * <p> The {@code initialSize} parameter may be used by the implementation 200 * as a <em>hint</em> as to the initial number of tasks it may submit. For 201 * example, it may be used to indicate the initial number of threads that 202 * wait on I/O events. 203 * 204 * <p> The executor is intended to be used exclusively by the resulting 205 * asynchronous channel group. Termination of the group results in the 206 * orderly {@link ExecutorService#shutdown shutdown} of the executor 207 * service. Shutting down the executor service by other means results in 208 * unspecified behavior. 209 * 210 * <p> The group is created by invoking the {@link 211 * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int) 212 * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide 213 * default {@link AsynchronousChannelProvider} object. 214 * 215 * @param executor 216 * The thread pool for the resulting group 217 * @param initialSize 218 * A value {@code >=0} or a negative value for implementation 219 * specific default 220 * 221 * @return A new asynchronous channel group 222 * 223 * @throws IOException 224 * If an I/O error occurs 225 * 226 * @see java.util.concurrent.Executors#newCachedThreadPool 227 */ withCachedThreadPool(ExecutorService executor, int initialSize)228 public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor, 229 int initialSize) 230 throws IOException 231 { 232 return AsynchronousChannelProvider.provider() 233 .openAsynchronousChannelGroup(executor, initialSize); 234 } 235 236 /** 237 * Creates an asynchronous channel group with a given thread pool. 238 * 239 * <p> The {@code executor} parameter is an {@code ExecutorService} that 240 * executes tasks submitted to dispatch completion results for operations 241 * initiated on asynchronous channels in the group. 242 * 243 * <p> Care should be taken when configuring the executor service. It 244 * should support <em>direct handoff</em> or <em>unbounded queuing</em> of 245 * submitted tasks, and the thread that invokes the {@link 246 * ExecutorService#execute execute} method should never invoke the task 247 * directly. An implementation may mandate additional constraints. 248 * 249 * <p> The executor is intended to be used exclusively by the resulting 250 * asynchronous channel group. Termination of the group results in the 251 * orderly {@link ExecutorService#shutdown shutdown} of the executor 252 * service. Shutting down the executor service by other means results in 253 * unspecified behavior. 254 * 255 * <p> The group is created by invoking the {@link 256 * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int) 257 * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide 258 * default {@link AsynchronousChannelProvider} object with an {@code 259 * initialSize} of {@code 0}. 260 * 261 * @param executor 262 * The thread pool for the resulting group 263 * 264 * @return A new asynchronous channel group 265 * 266 * @throws IOException 267 * If an I/O error occurs 268 */ withThreadPool(ExecutorService executor)269 public static AsynchronousChannelGroup withThreadPool(ExecutorService executor) 270 throws IOException 271 { 272 return AsynchronousChannelProvider.provider() 273 .openAsynchronousChannelGroup(executor, 0); 274 } 275 276 /** 277 * Tells whether or not this asynchronous channel group is shutdown. 278 * 279 * @return {@code true} if this asynchronous channel group is shutdown or 280 * has been marked for shutdown. 281 */ isShutdown()282 public abstract boolean isShutdown(); 283 284 /** 285 * Tells whether or not this group has terminated. 286 * 287 * <p> Where this method returns {@code true}, then the associated thread 288 * pool has also {@link ExecutorService#isTerminated terminated}. 289 * 290 * @return {@code true} if this group has terminated 291 */ isTerminated()292 public abstract boolean isTerminated(); 293 294 /** 295 * Initiates an orderly shutdown of the group. 296 * 297 * <p> This method marks the group as shutdown. Further attempts to construct 298 * channel that binds to this group will throw {@link ShutdownChannelGroupException}. 299 * The group terminates when all asynchronous channels in the group are 300 * closed, all actively executing completion handlers have run to completion, 301 * and all resources have been released. This method has no effect if the 302 * group is already shutdown. 303 */ shutdown()304 public abstract void shutdown(); 305 306 /** 307 * Shuts down the group and closes all open channels in the group. 308 * 309 * <p> In addition to the actions performed by the {@link #shutdown() shutdown} 310 * method, this method invokes the {@link AsynchronousChannel#close close} 311 * method on all open channels in the group. This method does not attempt to 312 * stop or interrupt threads that are executing completion handlers. The 313 * group terminates when all actively executing completion handlers have run 314 * to completion and all resources have been released. This method may be 315 * invoked at any time. If some other thread has already invoked it, then 316 * another invocation will block until the first invocation is complete, 317 * after which it will return without effect. 318 * 319 * @throws IOException 320 * If an I/O error occurs 321 */ shutdownNow()322 public abstract void shutdownNow() throws IOException; 323 324 /** 325 * Awaits termination of the group. 326 327 * <p> This method blocks until the group has terminated, or the timeout 328 * occurs, or the current thread is interrupted, whichever happens first. 329 * 330 * @param timeout 331 * The maximum time to wait, or zero or less to not wait 332 * @param unit 333 * The time unit of the timeout argument 334 * 335 * @return {@code true} if the group has terminated; {@code false} if the 336 * timeout elapsed before termination 337 * 338 * @throws InterruptedException 339 * If interrupted while waiting 340 */ awaitTermination(long timeout, TimeUnit unit)341 public abstract boolean awaitTermination(long timeout, TimeUnit unit) 342 throws InterruptedException; 343 } 344