001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.spi; 018 019import java.util.List; 020import java.util.concurrent.ExecutorService; 021import java.util.concurrent.ScheduledExecutorService; 022 023import org.apache.camel.ShutdownableService; 024import org.apache.camel.StaticService; 025 026/** 027 * Strategy to create thread pools. 028 * <p/> 029 * This manager is pluggable so you can plugin a custom provider, for example if you want to leverage 030 * the WorkManager for a JEE server. 031 * <p/> 032 * You may want to just implement a custom {@link ThreadPoolFactory} and rely on the 033 * {@link org.apache.camel.impl.DefaultExecutorServiceManager}, if that is sufficient. The {@link ThreadPoolFactory} 034 * is always used for creating the actual thread pools. You can implement a custom {@link ThreadPoolFactory} 035 * to leverage the WorkManager for a JEE server. 036 * <p/> 037 * The {@link ThreadPoolFactory} has pure JDK API, where as this {@link ExecutorServiceManager} has Camel API 038 * concepts such as {@link ThreadPoolProfile}. Therefore it may be easier to only implement a custom 039 * {@link ThreadPoolFactory}. 040 * <p/> 041 * This manager has fine grained methods for creating various thread pools, however custom strategies 042 * do not have to exactly create those kind of pools. Feel free to return a shared or different kind of pool. 043 * <p/> 044 * If you use the <tt>newXXX</tt> methods to create thread pools, then Camel will by default take care of 045 * shutting down those created pools when {@link org.apache.camel.CamelContext} is shutting down. 046 * <p/> 047 * For more information about shutting down thread pools see the {@link #shutdown(java.util.concurrent.ExecutorService)} 048 * and {@link #shutdownNow(java.util.concurrent.ExecutorService)}, and {@link #getShutdownAwaitTermination()} methods. 049 * Notice the details about using a graceful shutdown at fist, and then falling back to aggressive shutdown in case 050 * of await termination timeout occurred. 051 * 052 * @see ThreadPoolFactory 053 */ 054public interface ExecutorServiceManager extends ShutdownableService, StaticService { 055 056 /** 057 * Gets the {@link ThreadPoolFactory} to use for creating the thread pools. 058 * 059 * @return the thread pool factory 060 */ 061 ThreadPoolFactory getThreadPoolFactory(); 062 063 /** 064 * Sets a custom {@link ThreadPoolFactory} to use 065 * 066 * @param threadPoolFactory the thread pool factory 067 */ 068 void setThreadPoolFactory(ThreadPoolFactory threadPoolFactory); 069 070 /** 071 * Creates a full thread name 072 * 073 * @param name name which is appended to the full thread name 074 * @return the full thread name 075 */ 076 String resolveThreadName(String name); 077 078 /** 079 * Gets the thread pool profile by the given id 080 * 081 * @param id id of the thread pool profile to get 082 * @return the found profile, or <tt>null</tt> if not found 083 */ 084 ThreadPoolProfile getThreadPoolProfile(String id); 085 086 /** 087 * Registers the given thread pool profile 088 * 089 * @param profile the profile 090 */ 091 void registerThreadPoolProfile(ThreadPoolProfile profile); 092 093 /** 094 * Sets the default thread pool profile 095 * 096 * @param defaultThreadPoolProfile the new default thread pool profile 097 */ 098 void setDefaultThreadPoolProfile(ThreadPoolProfile defaultThreadPoolProfile); 099 100 /** 101 * Gets the default thread pool profile 102 * 103 * @return the default profile which are newer <tt>null</tt> 104 */ 105 ThreadPoolProfile getDefaultThreadPoolProfile(); 106 107 /** 108 * Sets the thread name pattern used for creating the full thread name. 109 * <p/> 110 * The default pattern is: <tt>Camel (#camelId#) thread ##counter# - #name#</tt> 111 * <p/> 112 * Where <tt>#camelId#</tt> is the name of the {@link org.apache.camel.CamelContext} 113 * <br/>and <tt>#counter#</tt> is a unique incrementing counter. 114 * <br/>and <tt>#name#</tt> is the regular thread name. 115 * <br/>You can also use <tt>#longName#</tt> is the long thread name which can includes endpoint parameters etc. 116 * 117 * @param pattern the pattern 118 * @throws IllegalArgumentException if the pattern is invalid. 119 */ 120 void setThreadNamePattern(String pattern) throws IllegalArgumentException; 121 122 /** 123 * Gets the thread name patter to use 124 * 125 * @return the pattern 126 */ 127 String getThreadNamePattern(); 128 129 /** 130 * Sets the time to wait for thread pools to shutdown orderly, when invoking the 131 * {@link #shutdown()} method. 132 * <p/> 133 * The default value is <tt>10000</tt> millis. 134 * 135 * @param timeInMillis time in millis. 136 */ 137 void setShutdownAwaitTermination(long timeInMillis); 138 139 /** 140 * Gets the time to wait for thread pools to shutdown orderly, when invoking the 141 * {@link #shutdown()} method. 142 * <p/> 143 * The default value is <tt>10000</tt> millis. 144 * 145 * @return the timeout value 146 */ 147 long getShutdownAwaitTermination(); 148 149 /** 150 * Creates a new daemon thread with the given name. 151 * 152 * @param name name which is appended to the thread name 153 * @param runnable a runnable to be executed by new thread instance 154 * @return the created thread 155 */ 156 Thread newThread(String name, Runnable runnable); 157 158 /** 159 * Creates a new thread pool using the default thread pool profile. 160 * 161 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 162 * @param name name which is appended to the thread name 163 * @return the created thread pool 164 */ 165 ExecutorService newDefaultThreadPool(Object source, String name); 166 167 /** 168 * Creates a new scheduled thread pool using the default thread pool profile. 169 * 170 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 171 * @param name name which is appended to the thread name 172 * @return the created thread pool 173 */ 174 ScheduledExecutorService newDefaultScheduledThreadPool(Object source, String name); 175 176 /** 177 * Creates a new thread pool using the given profile 178 * 179 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 180 * @param name name which is appended to the thread name 181 * @param profile the profile with the thread pool settings to use 182 * @return the created thread pool 183 */ 184 ExecutorService newThreadPool(Object source, String name, ThreadPoolProfile profile); 185 186 /** 187 * Creates a new thread pool using using the given profile id 188 * 189 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 190 * @param name name which is appended to the thread name 191 * @param profileId the id of the profile with the thread pool settings to use 192 * @return the created thread pool, or <tt>null</tt> if the thread pool profile could not be found 193 */ 194 ExecutorService newThreadPool(Object source, String name, String profileId); 195 196 /** 197 * Creates a new thread pool. 198 * <p/> 199 * Will fallback and use values from the default thread pool profile for keep alive time, rejection policy 200 * and other parameters which cannot be specified. 201 * 202 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 203 * @param name name which is appended to the thread name 204 * @param poolSize the core pool size 205 * @param maxPoolSize the maximum pool size 206 * @return the created thread pool 207 */ 208 ExecutorService newThreadPool(Object source, String name, int poolSize, int maxPoolSize); 209 210 /** 211 * Creates a new single-threaded thread pool. This is often used for background threads. 212 * <p/> 213 * Notice that there will always be a single thread in the pool. If you want the pool to be 214 * able to shrink to no threads, then use the <tt>newThreadPool</tt> method, and use 215 * 0 in core pool size, and 1 in max pool size. 216 * 217 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 218 * @param name name which is appended to the thread name 219 * @return the created thread pool 220 */ 221 ExecutorService newSingleThreadExecutor(Object source, String name); 222 223 /** 224 * Creates a new cached thread pool. 225 * <p/> 226 * <b>Important:</b> Using cached thread pool is discouraged as they have no upper bound and can overload the JVM. 227 * 228 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 229 * @param name name which is appended to the thread name 230 * @return the created thread pool 231 */ 232 ExecutorService newCachedThreadPool(Object source, String name); 233 234 /** 235 * Creates a new fixed thread pool. 236 * 237 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 238 * @param name name which is appended to the thread name 239 * @param poolSize the core pool size 240 * @return the created thread pool 241 */ 242 ExecutorService newFixedThreadPool(Object source, String name, int poolSize); 243 244 /** 245 * Creates a new scheduled thread pool. 246 * 247 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 248 * @param name name which is appended to the thread name 249 * @param poolSize the core pool size 250 * @return the created thread pool 251 */ 252 ScheduledExecutorService newScheduledThreadPool(Object source, String name, int poolSize); 253 254 /** 255 * Creates a new single-threaded thread pool. This is often used for background threads. 256 * 257 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 258 * @param name name which is appended to the thread name 259 * @return the created thread pool 260 */ 261 ScheduledExecutorService newSingleThreadScheduledExecutor(Object source, String name); 262 263 /** 264 * Creates a new scheduled thread pool using a profile 265 * 266 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 267 * @param name name which is appended to the thread name 268 * @param profile the profile with the thread pool settings to use 269 * @return created thread pool 270 */ 271 ScheduledExecutorService newScheduledThreadPool(Object source, String name, ThreadPoolProfile profile); 272 273 /** 274 * Creates a new scheduled thread pool using a profile id 275 * 276 * @param source the source object, usually it should be <tt>this</tt> passed in as parameter 277 * @param name name which is appended to the thread name 278 * @param profileId the id of the profile with the thread pool settings to use 279 * @return created thread pool 280 */ 281 ScheduledExecutorService newScheduledThreadPool(Object source, String name, String profileId); 282 283 /** 284 * Shutdown the given executor service (<b>not</b> graceful). 285 * <p/> 286 * This implementation will issues a regular shutdown of the executor service, 287 * ie calling {@link java.util.concurrent.ExecutorService#shutdown()} and return. 288 * 289 * @param executorService the executor service to shutdown 290 * @see java.util.concurrent.ExecutorService#shutdown() 291 */ 292 void shutdown(ExecutorService executorService); 293 294 /** 295 * Shutdown the given executor service graceful at first, and then aggressively 296 * if the await termination timeout was hit. 297 * <p/> 298 * Will try to perform an orderly shutdown by giving the running threads 299 * time to complete tasks, before going more aggressively by doing a 300 * {@link #shutdownNow(java.util.concurrent.ExecutorService)} which 301 * forces a shutdown. The {@link #getShutdownAwaitTermination()} 302 * is used as timeout value waiting for orderly shutdown to 303 * complete normally, before going aggressively. 304 * 305 * @param executorService the executor service to shutdown 306 * @see java.util.concurrent.ExecutorService#shutdown() 307 * @see #getShutdownAwaitTermination() 308 */ 309 void shutdownGraceful(ExecutorService executorService); 310 311 /** 312 * Shutdown the given executor service graceful at first, and then aggressively 313 * if the await termination timeout was hit. 314 * <p/> 315 * Will try to perform an orderly shutdown by giving the running threads 316 * time to complete tasks, before going more aggressively by doing a 317 * {@link #shutdownNow(java.util.concurrent.ExecutorService)} which 318 * forces a shutdown. The parameter <tt>shutdownAwaitTermination</tt> 319 * is used as timeout value waiting for orderly shutdown to 320 * complete normally, before going aggressively. 321 * 322 * @param executorService the executor service to shutdown 323 * @param shutdownAwaitTermination timeout in millis to wait for orderly shutdown 324 * @see java.util.concurrent.ExecutorService#shutdown() 325 */ 326 void shutdownGraceful(ExecutorService executorService, long shutdownAwaitTermination); 327 328 /** 329 * Shutdown now the given executor service aggressively. 330 * <p/> 331 * This implementation will issues a regular shutdownNow of the executor service, 332 * ie calling {@link java.util.concurrent.ExecutorService#shutdownNow()} and return. 333 * 334 * @param executorService the executor service to shutdown now 335 * @return list of tasks that never commenced execution 336 * @see java.util.concurrent.ExecutorService#shutdownNow() 337 */ 338 List<Runnable> shutdownNow(ExecutorService executorService); 339 340 /** 341 * Awaits the termination of the thread pool. 342 * <p/> 343 * This implementation will log every 2nd second at INFO level that we are waiting, so the end user 344 * can see we are not hanging in case it takes longer time to terminate the pool. 345 * 346 * @param executorService the thread pool 347 * @param shutdownAwaitTermination time in millis to use as timeout 348 * @return <tt>true</tt> if the pool is terminated, or <tt>false</tt> if we timed out 349 * @throws InterruptedException is thrown if we are interrupted during waiting 350 */ 351 boolean awaitTermination(ExecutorService executorService, long shutdownAwaitTermination) throws InterruptedException; 352 353}