1 /*
   2  * Copyright (c) 2007, 2017, 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 class="striped">
  64  * <caption style="display:none:">System properties</caption>
  65  *   <thead>
  66  *   <tr>
  67  *     <th>System property</th>
  68  *     <th>Description</th>
  69  *   </tr>
  70  *   </thead>
  71  *   <tbody>
  72  *   <tr>
  73  *     <td> {@code java.nio.channels.DefaultThreadPool.threadFactory} </td>
  74  *     <td> The value of this property is taken to be the fully-qualified name
  75  *     of a concrete {@link java.util.concurrent.ThreadFactory ThreadFactory}
  76  *     class. The class is loaded using the system class loader and instantiated.
  77  *     The factory's {@link java.util.concurrent.ThreadFactory#newThread
  78  *     newThread} method is invoked to create each thread for the default
  79  *     group's thread pool. If the process to load and instantiate the value
  80  *     of the property fails then an unspecified error is thrown during the
  81  *     construction of the default group. </td>
  82  *   </tr>
  83  *   <tr>
  84  *     <td> {@code java.nio.channels.DefaultThreadPool.initialSize} </td>
  85  *     <td> The value of the {@code initialSize} parameter for the default
  86  *     group (see {@link #withCachedThreadPool withCachedThreadPool}).
  87  *     The value of the property is taken to be the {@code String}
  88  *     representation of an {@code Integer} that is the initial size parameter.
  89  *     If the value cannot be parsed as an {@code Integer} it causes an
  90  *     unspecified error to be thrown during the construction of the default
  91  *     group. </td>
  92  *   </tr>
  93  *   </tbody>
  94  * </table>
  95  *
  96  * <a id="threading"></a><h2>Threading</h2>
  97  *
  98  * <p> The completion handler for an I/O operation initiated on a channel bound
  99  * to a group is guaranteed to be invoked by one of the pooled threads in the
 100  * group. This ensures that the completion handler is run by a thread with the
 101  * expected <em>identity</em>.
 102  *
 103  * <p> Where an I/O operation completes immediately, and the initiating thread
 104  * is one of the pooled threads in the group then the completion handler may
 105  * be invoked directly by the initiating thread. To avoid stack overflow, an
 106  * implementation may impose a limit as to the number of activations on the
 107  * thread stack. Some I/O operations may prohibit invoking the completion
 108  * handler directly by the initiating thread (see {@link
 109  * AsynchronousServerSocketChannel#accept(Object,CompletionHandler) accept}).
 110  *
 111  * <a id="shutdown"></a><h2>Shutdown and Termination</h2>
 112  *
 113  * <p> The {@link #shutdown() shutdown} method is used to initiate an <em>orderly
 114  * shutdown</em> of a group. An orderly shutdown marks the group as shutdown;
 115  * further attempts to construct a channel that binds to the group will throw
 116  * {@link ShutdownChannelGroupException}. Whether or not a group is shutdown can
 117  * be tested using the {@link #isShutdown() isShutdown} method. Once shutdown,
 118  * the group <em>terminates</em> when all asynchronous channels that are bound to
 119  * the group are closed, all actively executing completion handlers have run to
 120  * completion, and resources used by the group are released. No attempt is made
 121  * to stop or interrupt threads that are executing completion handlers. The
 122  * {@link #isTerminated() isTerminated} method is used to test if the group has
 123  * terminated, and the {@link #awaitTermination awaitTermination} method can be
 124  * used to block until the group has terminated.
 125  *
 126  * <p> The {@link #shutdownNow() shutdownNow} method can be used to initiate a
 127  * <em>forceful shutdown</em> of the group. In addition to the actions performed
 128  * by an orderly shutdown, the {@code shutdownNow} method closes all open channels
 129  * in the group as if by invoking the {@link AsynchronousChannel#close close}
 130  * method.
 131  *
 132  * @since 1.7
 133  *
 134  * @see AsynchronousSocketChannel#open(AsynchronousChannelGroup)
 135  * @see AsynchronousServerSocketChannel#open(AsynchronousChannelGroup)
 136  */
 137 
 138 public abstract class AsynchronousChannelGroup {
 139     private final AsynchronousChannelProvider provider;
 140 
 141     /**
 142      * Initialize a new instance of this class.
 143      *
 144      * @param   provider
 145      *          The asynchronous channel provider for this group
 146      */
 147     protected AsynchronousChannelGroup(AsynchronousChannelProvider provider) {
 148         this.provider = provider;
 149     }
 150 
 151     /**
 152      * Returns the provider that created this channel group.
 153      *
 154      * @return  The provider that created this channel group
 155      */
 156     public final AsynchronousChannelProvider provider() {
 157         return provider;
 158     }
 159 
 160     /**
 161      * Creates an asynchronous channel group with a fixed thread pool.
 162      *
 163      * <p> The resulting asynchronous channel group reuses a fixed number of
 164      * threads. At any point, at most {@code nThreads} threads will be active
 165      * processing tasks that are submitted to handle I/O events and dispatch
 166      * completion results for operations initiated on asynchronous channels in
 167      * the group.
 168      *
 169      * <p> The group is created by invoking the {@link
 170      * AsynchronousChannelProvider#openAsynchronousChannelGroup(int,ThreadFactory)
 171      * openAsynchronousChannelGroup(int,ThreadFactory)} method of the system-wide
 172      * default {@link AsynchronousChannelProvider} object.
 173      *
 174      * @param   nThreads
 175      *          The number of threads in the pool
 176      * @param   threadFactory
 177      *          The factory to use when creating new threads
 178      *
 179      * @return  A new asynchronous channel group
 180      *
 181      * @throws  IllegalArgumentException
 182      *          If {@code nThreads <= 0}
 183      * @throws  IOException
 184      *          If an I/O error occurs
 185      */
 186     public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,
 187                                                                ThreadFactory threadFactory)
 188         throws IOException
 189     {
 190         return AsynchronousChannelProvider.provider()
 191             .openAsynchronousChannelGroup(nThreads, threadFactory);
 192     }
 193 
 194     /**
 195      * Creates an asynchronous channel group with a given thread pool that
 196      * creates new threads as needed.
 197      *
 198      * <p> The {@code executor} parameter is an {@code ExecutorService} that
 199      * creates new threads as needed to execute tasks that are submitted to
 200      * handle I/O events and dispatch completion results for operations initiated
 201      * on asynchronous channels in the group. It may reuse previously constructed
 202      * threads when they are available.
 203      *
 204      * <p> The {@code initialSize} parameter may be used by the implementation
 205      * as a <em>hint</em> as to the initial number of tasks it may submit. For
 206      * example, it may be used to indicate the initial number of threads that
 207      * wait on I/O events.
 208      *
 209      * <p> The executor is intended to be used exclusively by the resulting
 210      * asynchronous channel group. Termination of the group results in the
 211      * orderly  {@link ExecutorService#shutdown shutdown} of the executor
 212      * service. Shutting down the executor service by other means results in
 213      * unspecified behavior.
 214      *
 215      * <p> The group is created by invoking the {@link
 216      * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
 217      * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
 218      * default {@link AsynchronousChannelProvider} object.
 219      *
 220      * @param   executor
 221      *          The thread pool for the resulting group
 222      * @param   initialSize
 223      *          A value {@code >=0} or a negative value for implementation
 224      *          specific default
 225      *
 226      * @return  A new asynchronous channel group
 227      *
 228      * @throws  IOException
 229      *          If an I/O error occurs
 230      *
 231      * @see java.util.concurrent.Executors#newCachedThreadPool
 232      */
 233     public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,
 234                                                                 int initialSize)
 235         throws IOException
 236     {
 237         return AsynchronousChannelProvider.provider()
 238             .openAsynchronousChannelGroup(executor, initialSize);
 239     }
 240 
 241     /**
 242      * Creates an asynchronous channel group with a given thread pool.
 243      *
 244      * <p> The {@code executor} parameter is an {@code ExecutorService} that
 245      * executes tasks submitted to dispatch completion results for operations
 246      * initiated on asynchronous channels in the group.
 247      *
 248      * <p> Care should be taken when configuring the executor service. It
 249      * should support <em>direct handoff</em> or <em>unbounded queuing</em> of
 250      * submitted tasks, and the thread that invokes the {@link
 251      * ExecutorService#execute execute} method should never invoke the task
 252      * directly. An implementation may mandate additional constraints.
 253      *
 254      * <p> The executor is intended to be used exclusively by the resulting
 255      * asynchronous channel group. Termination of the group results in the
 256      * orderly  {@link ExecutorService#shutdown shutdown} of the executor
 257      * service. Shutting down the executor service by other means results in
 258      * unspecified behavior.
 259      *
 260      * <p> The group is created by invoking the {@link
 261      * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
 262      * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
 263      * default {@link AsynchronousChannelProvider} object with an {@code
 264      * initialSize} of {@code 0}.
 265      *
 266      * @param   executor
 267      *          The thread pool for the resulting group
 268      *
 269      * @return  A new asynchronous channel group
 270      *
 271      * @throws  IOException
 272      *          If an I/O error occurs
 273      */
 274     public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)
 275         throws IOException
 276     {
 277         return AsynchronousChannelProvider.provider()
 278             .openAsynchronousChannelGroup(executor, 0);
 279     }
 280 
 281     /**
 282      * Tells whether or not this asynchronous channel group is shutdown.
 283      *
 284      * @return  {@code true} if this asynchronous channel group is shutdown or
 285      *          has been marked for shutdown.
 286      */
 287     public abstract boolean isShutdown();
 288 
 289     /**
 290      * Tells whether or not this group has terminated.
 291      *
 292      * <p> Where this method returns {@code true}, then the associated thread
 293      * pool has also {@link ExecutorService#isTerminated terminated}.
 294      *
 295      * @return  {@code true} if this group has terminated
 296      */
 297     public abstract boolean isTerminated();
 298 
 299     /**
 300      * Initiates an orderly shutdown of the group.
 301      *
 302      * <p> This method marks the group as shutdown. Further attempts to construct
 303      * channel that binds to this group will throw {@link ShutdownChannelGroupException}.
 304      * The group terminates when all asynchronous channels in the group are
 305      * closed, all actively executing completion handlers have run to completion,
 306      * and all resources have been released. This method has no effect if the
 307      * group is already shutdown.
 308      */
 309     public abstract void shutdown();
 310 
 311     /**
 312      * Shuts down the group and closes all open channels in the group.
 313      *
 314      * <p> In addition to the actions performed by the {@link #shutdown() shutdown}
 315      * method, this method invokes the {@link AsynchronousChannel#close close}
 316      * method on all open channels in the group. This method does not attempt to
 317      * stop or interrupt threads that are executing completion handlers. The
 318      * group terminates when all actively executing completion handlers have run
 319      * to completion and all resources have been released. This method may be
 320      * invoked at any time. If some other thread has already invoked it, then
 321      * another invocation will block until the first invocation is complete,
 322      * after which it will return without effect.
 323      *
 324      * @throws  IOException
 325      *          If an I/O error occurs
 326      */
 327     public abstract void shutdownNow() throws IOException;
 328 
 329     /**
 330      * Awaits termination of the group.
 331 
 332      * <p> This method blocks until the group has terminated, or the timeout
 333      * occurs, or the current thread is interrupted, whichever happens first.
 334      *
 335      * @param   timeout
 336      *          The maximum time to wait, or zero or less to not wait
 337      * @param   unit
 338      *          The time unit of the timeout argument
 339      *
 340      * @return  {@code true} if the group has terminated; {@code false} if the
 341      *          timeout elapsed before termination
 342      *
 343      * @throws  InterruptedException
 344      *          If interrupted while waiting
 345      */
 346     public abstract boolean awaitTermination(long timeout, TimeUnit unit)
 347         throws InterruptedException;
 348 }