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