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 scope="col">System property</th>
68  *     <th scope="col">Description</th>
69  *   </tr>
70  *   </thead>
71  *   <tbody>
72  *   <tr>
73  *     <th scope="row"> {@code java.nio.channels.DefaultThreadPool.threadFactory} </th>
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  *     <th scope="row"> {@code java.nio.channels.DefaultThreadPool.initialSize} </th>
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      */
AsynchronousChannelGroup(AsynchronousChannelProvider provider)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      */
provider()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      */
withFixedThreadPool(int nThreads, ThreadFactory threadFactory)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      */
withCachedThreadPool(ExecutorService executor, int initialSize)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      */
withThreadPool(ExecutorService executor)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      */
isShutdown()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      */
isTerminated()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      */
shutdown()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      */
shutdownNow()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      */
awaitTermination(long timeout, TimeUnit unit)346     public abstract boolean awaitTermination(long timeout, TimeUnit unit)
347         throws InterruptedException;
348 }
349