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 id="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 id="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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 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      */
 341     public abstract boolean awaitTermination(long timeout, TimeUnit unit)
 342         throws InterruptedException;
 343 }