Merge branch 'master' of ../controller
[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      * @param loggerIdentity
50      *               the class to use as logger name for logging uncaught exceptions from the threads.
51      * @return a new ExecutorService with the specified configuration.
52      */
53     public static ExecutorService newBoundedFastThreadPool(int maximumPoolSize,
54             int maximumQueueSize, String threadPrefix, Class<?> loggerIdentity) {
55         return new FastThreadPoolExecutor(maximumPoolSize, maximumQueueSize, threadPrefix, loggerIdentity);
56     }
57
58     /**
59      * Creates an ExecutorService similar to {@link #newBoundedFastThreadPool } except that it
60      * handles rejected tasks by running them in the same thread as the caller. Therefore if the
61      * queue is full, the caller submitting the task will be blocked until the task completes. In
62      * this manner, tasks are never rejected.
63      *
64      * @param maximumPoolSize
65      *            the maximum number of threads to allow in the pool. Threads will terminate after
66      *            being idle for 15 seconds.
67      * @param maximumQueueSize
68      *            the capacity of the queue.
69      * @param threadPrefix
70      *            the name prefix for threads created by this executor.
71      * @param loggerIdentity
72      *               the class to use as logger name for logging uncaught exceptions from the threads.
73      * @return a new ExecutorService with the specified configuration.
74      */
75     public static ExecutorService newBlockingBoundedFastThreadPool(int maximumPoolSize,
76             int maximumQueueSize, String threadPrefix, Class<?> loggerIdentity) {
77
78         FastThreadPoolExecutor executor = new FastThreadPoolExecutor(maximumPoolSize, maximumQueueSize, threadPrefix,
79                 loggerIdentity);
80         executor.setRejectedExecutionHandler(CountingRejectedExecutionHandler.newCallerRunsPolicy());
81         return executor;
82     }
83
84     /**
85      * Creates an ExecutorService with a specified bounded queue capacity that favors reusing
86      * previously constructed threads, when they are available, over creating new threads. When a
87      * task is submitted, if no existing thread is available, a new thread will be created and added
88      * to the pool. If there is an existing idle thread available, the task will be handed to that
89      * thread to execute. If the specified maximum thread limit is reached, subsequent tasks will be
90      * queued and will execute as threads become available. If the maximum queue capacity is
91      * reached, subsequent tasks will be rejected.
92      *
93      * <p>Threads that have not been used for sixty seconds are terminated and removed from the pool.
94      * Thus, a pool that remains idle for long enough will not consume any resources.
95      *
96      * <p>By reusing threads when possible, this executor optimizes for reduced memory and thread
97      * resource overhead at the expense of execution time.
98      *
99      * <p>If you need an executor with faster execution time where increased memory and thread resource
100      * overhead is acceptable, consider using {@link #newBoundedFastThreadPool }.
101      *
102      * @param maximumPoolSize
103      *            the maximum number of threads to allow in the pool. Threads will terminate after
104      *            being idle for 60 seconds.
105      * @param maximumQueueSize
106      *            the capacity of the queue.
107      * @param threadPrefix
108      *            the name prefix for threads created by this executor.
109      * @return a new ExecutorService with the specified configuration.
110      */
111     public static ExecutorService newBoundedCachedThreadPool(int maximumPoolSize,
112             int maximumQueueSize, String threadPrefix, Class<?> loggerIdentity) {
113         return new CachedThreadPoolExecutor(maximumPoolSize, maximumQueueSize, threadPrefix, loggerIdentity);
114     }
115
116     /**
117      * Creates an ExecutorService similar to {@link #newBoundedCachedThreadPool } except that it
118      * handles rejected tasks by running them in the same thread as the caller. Therefore if the
119      * queue is full, the caller submitting the task will be blocked until the task completes. In
120      * this manner, tasks are never rejected.
121      *
122      * @param maximumPoolSize
123      *            the maximum number of threads to allow in the pool. Threads will terminate after
124      *            being idle for 60 seconds.
125      * @param maximumQueueSize
126      *            the capacity of the queue.
127      * @param threadPrefix
128      *            the name prefix for threads created by this executor.
129      * @return a new ExecutorService with the specified configuration.
130      */
131     public static ExecutorService newBlockingBoundedCachedThreadPool(int maximumPoolSize,
132             int maximumQueueSize, String threadPrefix, Class<?> loggerIdentity) {
133
134         CachedThreadPoolExecutor executor = new CachedThreadPoolExecutor(maximumPoolSize, maximumQueueSize,
135                 threadPrefix, loggerIdentity);
136         executor.setRejectedExecutionHandler(CountingRejectedExecutionHandler.newCallerRunsPolicy());
137         return executor;
138     }
139
140     /**
141      * Creates an ExecutorService that uses a single worker thread operating off a bounded queue
142      * with the specified capacity. Tasks are guaranteed to execute sequentially, and no more than
143      * one task will be active at any given time. If the maximum queue capacity is reached,
144      * subsequent tasks will be rejected.
145      *
146      * @param maximumQueueSize
147      *            the capacity of the queue.
148      * @param threadPrefix
149      *            the name prefix for the thread created by this executor.
150      * @param loggerIdentity
151      *               the class to use as logger name for logging uncaught exceptions from the threads.
152      * @return a new ExecutorService with the specified configuration.
153      */
154     public static ExecutorService newBoundedSingleThreadExecutor(int maximumQueueSize,
155             String threadPrefix, Class<?> loggerIdentity) {
156         return new FastThreadPoolExecutor(1, maximumQueueSize, Long.MAX_VALUE, TimeUnit.SECONDS,
157                 threadPrefix, loggerIdentity);
158     }
159
160 }