929ecc01069b83694048f4a5a3a65ba78108cb1e
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / concurrent / SpecialExecutors.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.yangtools.util.concurrent;
10
11 import java.util.concurrent.ExecutorService;
12 import java.util.concurrent.TimeUnit;
13
14 /**
15  * Factory methods for creating {@link ExecutorService} instances with specific configurations.
16
17  * @author Thomas Pantelis
18  */
19 public final class SpecialExecutors {
20
21     private SpecialExecutors() {
22     }
23
24     /**
25      * Creates an ExecutorService with a specified bounded queue capacity that favors creating new
26      * threads over queuing, as the former is faster, so threads will only be reused when the thread
27      * limit is exceeded and tasks are queued. If the maximum queue capacity is reached, subsequent
28      * tasks will be rejected.
29      *
30      * <p>For example, if the maximum number of threads is 100 and 100 short-lived tasks are submitted
31      * within say 10 seconds, then 100 threads will be created and used - previously constructed
32      * idle threads will not be reused. This provides the fastest execution of the 100 tasks at the
33      * expense of memory and thread resource overhead. Therefore it is advisable to specify a
34      * relatively small thread limit (probably no more than 50).
35      *
36      * <p>Threads that have not been used for 15 seconds are terminated and removed from the pool.
37      * Thus, a pool that remains idle for long enough will not consume any resources.
38      *
39      * <p>If you need an executor with less memory and thread resource overhead where slower execution
40      * time is acceptable, consider using {@link #newBoundedCachedThreadPool }.
41      *
42      * @param maximumPoolSize
43      *            the maximum number of threads to allow in the pool. Threads will terminate after
44      *            being idle for 15 seconds.
45      * @param maximumQueueSize
46      *            the capacity of the queue.
47      * @param threadPrefix
48      *            the name prefix for threads created by this executor.
49      * @return a new ExecutorService with the specified configuration.
50      */
51     public static ExecutorService newBoundedFastThreadPool( int maximumPoolSize,
52             int maximumQueueSize, String threadPrefix ) {
53         return new FastThreadPoolExecutor( maximumPoolSize, maximumQueueSize, threadPrefix );
54     }
55
56     /**
57      * Creates an ExecutorService similar to {@link #newBoundedFastThreadPool } except that it
58      * handles rejected tasks by running them in the same thread as the caller. Therefore if the
59      * queue is full, the caller submitting the task will be blocked until the task completes. In
60      * this manner, tasks are never rejected.
61      *
62      * @param maximumPoolSize
63      *            the maximum number of threads to allow in the pool. Threads will terminate after
64      *            being idle for 15 seconds.
65      * @param maximumQueueSize
66      *            the capacity of the queue.
67      * @param threadPrefix
68      *            the name prefix for threads created by this executor.
69      * @return a new ExecutorService with the specified configuration.
70      */
71     public static ExecutorService newBlockingBoundedFastThreadPool( int maximumPoolSize,
72             int maximumQueueSize, String threadPrefix ) {
73
74         FastThreadPoolExecutor executor =
75                 new FastThreadPoolExecutor( maximumPoolSize, maximumQueueSize, threadPrefix );
76         executor.setRejectedExecutionHandler( CountingRejectedExecutionHandler.newCallerRunsPolicy() );
77         return executor;
78     }
79
80     /**
81      * Creates an ExecutorService with a specified bounded queue capacity that favors reusing
82      * previously constructed threads, when they are available, over creating new threads. When a
83      * task is submitted, if no existing thread is available, a new thread will be created and added
84      * to the pool. If there is an existing idle thread available, the task will be handed to that
85      * thread to execute. If the specified maximum thread limit is reached, subsequent tasks will be
86      * queued and will execute as threads become available. If the maximum queue capacity is
87      * reached, subsequent tasks will be rejected.
88      *
89      * <p>Threads that have not been used for sixty seconds are terminated and removed from the pool.
90      * Thus, a pool that remains idle for long enough will not consume any resources.
91      *
92      * <p>By reusing threads when possible, this executor optimizes for reduced memory and thread
93      * resource overhead at the expense of execution time.
94      *
95      * <p>If you need an executor with faster execution time where increased memory and thread resource
96      * overhead is acceptable, consider using {@link #newBoundedFastThreadPool }.
97      *
98      * @param maximumPoolSize
99      *            the maximum number of threads to allow in the pool. Threads will terminate after
100      *            being idle for 60 seconds.
101      * @param maximumQueueSize
102      *            the capacity of the queue.
103      * @param threadPrefix
104      *            the name prefix for threads created by this executor.
105      * @return a new ExecutorService with the specified configuration.
106      */
107     public static ExecutorService newBoundedCachedThreadPool( int maximumPoolSize,
108             int maximumQueueSize, String threadPrefix ) {
109         return new CachedThreadPoolExecutor( maximumPoolSize, maximumQueueSize, threadPrefix );
110     }
111
112     /**
113      * Creates an ExecutorService similar to {@link #newBoundedCachedThreadPool } except that it
114      * handles rejected tasks by running them in the same thread as the caller. Therefore if the
115      * queue is full, the caller submitting the task will be blocked until the task completes. In
116      * this manner, tasks are never rejected.
117      *
118      * @param maximumPoolSize
119      *            the maximum number of threads to allow in the pool. Threads will terminate after
120      *            being idle for 60 seconds.
121      * @param maximumQueueSize
122      *            the capacity of the queue.
123      * @param threadPrefix
124      *            the name prefix for threads created by this executor.
125      * @return a new ExecutorService with the specified configuration.
126      */
127     public static ExecutorService newBlockingBoundedCachedThreadPool( int maximumPoolSize,
128             int maximumQueueSize, String threadPrefix ) {
129
130         CachedThreadPoolExecutor executor =
131                 new CachedThreadPoolExecutor( maximumPoolSize, maximumQueueSize, threadPrefix );
132         executor.setRejectedExecutionHandler( CountingRejectedExecutionHandler.newCallerRunsPolicy() );
133         return executor;
134     }
135
136     /**
137      * Creates an ExecutorService that uses a single worker thread operating off a bounded queue
138      * with the specified capacity. Tasks are guaranteed to execute sequentially, and no more than
139      * one task will be active at any given time. If the maximum queue capacity is reached,
140      * subsequent tasks will be rejected.
141      *
142      * @param maximumQueueSize
143      *            the capacity of the queue.
144      * @param threadPrefix
145      *            the name prefix for the thread created by this executor.
146      * @return a new ExecutorService with the specified configuration.
147      */
148     public static ExecutorService newBoundedSingleThreadExecutor( int maximumQueueSize,
149             String threadPrefix ) {
150         return new FastThreadPoolExecutor( 1, maximumQueueSize, Long.MAX_VALUE, TimeUnit.SECONDS,
151                 threadPrefix );
152     }
153 }