| Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
| BasicThreadFactory |
|
| 1.6875;1.688 | ||||
| BasicThreadFactory$1 |
|
| 1.6875;1.688 | ||||
| BasicThreadFactory$Builder |
|
| 1.6875;1.688 |
| 1 | /* | |
| 2 | * Licensed to the Apache Software Foundation (ASF) under one or more | |
| 3 | * contributor license agreements. See the NOTICE file distributed with | |
| 4 | * this work for additional information regarding copyright ownership. | |
| 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 | |
| 6 | * (the "License"); you may not use this file except in compliance with | |
| 7 | * the License. You may obtain a copy of the License at | |
| 8 | * | |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 | |
| 10 | * | |
| 11 | * Unless required by applicable law or agreed to in writing, software | |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, | |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 14 | * See the License for the specific language governing permissions and | |
| 15 | * limitations under the License. | |
| 16 | */ | |
| 17 | package org.apache.commons.lang3.concurrent; | |
| 18 | ||
| 19 | import java.util.concurrent.Executors; | |
| 20 | import java.util.concurrent.ThreadFactory; | |
| 21 | import java.util.concurrent.atomic.AtomicLong; | |
| 22 | ||
| 23 | /** | |
| 24 | * <p> | |
| 25 | * An implementation of the {@code ThreadFactory} interface that provides some | |
| 26 | * configuration options for the threads it creates. | |
| 27 | * </p> | |
| 28 | * <p> | |
| 29 | * A {@code ThreadFactory} is used for instance by an {@code ExecutorService} to | |
| 30 | * create the threads it uses for executing tasks. In many cases users do not | |
| 31 | * have to care about a {@code ThreadFactory} because the default one used by an | |
| 32 | * {@code ExecutorService} will do. However, if there are special requirements | |
| 33 | * for the threads, a custom {@code ThreadFactory} has to be created. | |
| 34 | * </p> | |
| 35 | * <p> | |
| 36 | * This class provides some frequently needed configuration options for the | |
| 37 | * threads it creates. These are the following: | |
| 38 | * <ul> | |
| 39 | * <li>A name pattern for the threads created by this factory can be specified. | |
| 40 | * This is often useful if an application uses multiple executor services for | |
| 41 | * different purposes. If the names of the threads used by these services have | |
| 42 | * meaningful names, log output or exception traces can be much easier to read. | |
| 43 | * Naming patterns are <em>format strings</em> as used by the {@code | |
| 44 | * String.format()} method. The string can contain the place holder {@code %d} | |
| 45 | * which will be replaced by the number of the current thread ({@code | |
| 46 | * ThreadFactoryImpl} keeps a counter of the threads it has already created). | |
| 47 | * For instance, the naming pattern {@code "My %d. worker thread"} will result | |
| 48 | * in thread names like {@code "My 1. worker thread"}, {@code | |
| 49 | * "My 2. worker thread"} and so on.</li> | |
| 50 | * <li>A flag whether the threads created by this factory should be daemon | |
| 51 | * threads. This can impact the exit behavior of the current Java application | |
| 52 | * because the JVM shuts down if there are only daemon threads running.</li> | |
| 53 | * <li>The priority of the thread. Here an integer value can be provided. The | |
| 54 | * {@code java.lang.Thread} class defines constants for valid ranges of priority | |
| 55 | * values.</li> | |
| 56 | * <li>The {@code UncaughtExceptionHandler} for the thread. This handler is | |
| 57 | * called if an uncaught exception occurs within the thread.</li> | |
| 58 | * </ul> | |
| 59 | * </p> | |
| 60 | * <p> | |
| 61 | * {@code BasicThreadFactory} wraps another thread factory which actually | |
| 62 | * creates new threads. The configuration options are set on the threads created | |
| 63 | * by the wrapped thread factory. On construction time the factory to be wrapped | |
| 64 | * can be specified. If none is provided, a default {@code ThreadFactory} is | |
| 65 | * used. | |
| 66 | * </p> | |
| 67 | * <p> | |
| 68 | * Instances of {@code BasicThreadFactory} are not created directly, but the | |
| 69 | * nested {@code Builder} class is used for this purpose. Using the builder only | |
| 70 | * the configuration options an application is interested in need to be set. The | |
| 71 | * following example shows how a {@code BasicThreadFactory} is created and | |
| 72 | * installed in an {@code ExecutorService}: | |
| 73 | * | |
| 74 | * <pre> | |
| 75 | * // Create a factory that produces daemon threads with a naming pattern and | |
| 76 | * // a priority | |
| 77 | * BasicThreadFactory factory = new BasicThreadFactory.Builder() | |
| 78 | * .namingPattern("workerthread-%d") | |
| 79 | * .daemon(true) | |
| 80 | * .priority(Thread.MAX_PRIORITY) | |
| 81 | * .build(); | |
| 82 | * // Create an executor service for single-threaded execution | |
| 83 | * ExecutorService exec = Executors.newSingleThreadExecutor(factory); | |
| 84 | * </pre> | |
| 85 | * </p> | |
| 86 | * | |
| 87 | * @since 3.0 | |
| 88 | * @version $Id: BasicThreadFactory.java 1436770 2013-01-22 07:09:45Z ggregory $ | |
| 89 | */ | |
| 90 | 13 | public class BasicThreadFactory implements ThreadFactory { |
| 91 | /** A counter for the threads created by this factory. */ | |
| 92 | private final AtomicLong threadCounter; | |
| 93 | ||
| 94 | /** Stores the wrapped factory. */ | |
| 95 | private final ThreadFactory wrappedFactory; | |
| 96 | ||
| 97 | /** Stores the uncaught exception handler. */ | |
| 98 | private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler; | |
| 99 | ||
| 100 | /** Stores the naming pattern for newly created threads. */ | |
| 101 | private final String namingPattern; | |
| 102 | ||
| 103 | /** Stores the priority. */ | |
| 104 | private final Integer priority; | |
| 105 | ||
| 106 | /** Stores the daemon status flag. */ | |
| 107 | private final Boolean daemonFlag; | |
| 108 | ||
| 109 | /** | |
| 110 | * Creates a new instance of {@code ThreadFactoryImpl} and configures it | |
| 111 | * from the specified {@code Builder} object. | |
| 112 | * | |
| 113 | * @param builder the {@code Builder} object | |
| 114 | */ | |
| 115 | 13 | private BasicThreadFactory(final Builder builder) { |
| 116 | 13 | if (builder.wrappedFactory == null) { |
| 117 | 3 | wrappedFactory = Executors.defaultThreadFactory(); |
| 118 | } else { | |
| 119 | 10 | wrappedFactory = builder.wrappedFactory; |
| 120 | } | |
| 121 | ||
| 122 | 13 | namingPattern = builder.namingPattern; |
| 123 | 13 | priority = builder.priority; |
| 124 | 13 | daemonFlag = builder.daemonFlag; |
| 125 | 13 | uncaughtExceptionHandler = builder.exceptionHandler; |
| 126 | ||
| 127 | 13 | threadCounter = new AtomicLong(); |
| 128 | 13 | } |
| 129 | ||
| 130 | /** | |
| 131 | * Returns the wrapped {@code ThreadFactory}. This factory is used for | |
| 132 | * actually creating threads. This method never returns <b>null</b>. If no | |
| 133 | * {@code ThreadFactory} was passed when this object was created, a default | |
| 134 | * thread factory is returned. | |
| 135 | * | |
| 136 | * @return the wrapped {@code ThreadFactory} | |
| 137 | */ | |
| 138 | public final ThreadFactory getWrappedFactory() { | |
| 139 | 25 | return wrappedFactory; |
| 140 | } | |
| 141 | ||
| 142 | /** | |
| 143 | * Returns the naming pattern for naming newly created threads. Result can | |
| 144 | * be <b>null</b> if no naming pattern was provided. | |
| 145 | * | |
| 146 | * @return the naming pattern | |
| 147 | */ | |
| 148 | public final String getNamingPattern() { | |
| 149 | 36 | return namingPattern; |
| 150 | } | |
| 151 | ||
| 152 | /** | |
| 153 | * Returns the daemon flag. This flag determines whether newly created | |
| 154 | * threads should be daemon threads. If <b>true</b>, this factory object | |
| 155 | * calls {@code setDaemon(true)} on the newly created threads. Result can be | |
| 156 | * <b>null</b> if no daemon flag was provided at creation time. | |
| 157 | * | |
| 158 | * @return the daemon flag | |
| 159 | */ | |
| 160 | public final Boolean getDaemonFlag() { | |
| 161 | 26 | return daemonFlag; |
| 162 | } | |
| 163 | ||
| 164 | /** | |
| 165 | * Returns the priority of the threads created by this factory. Result can | |
| 166 | * be <b>null</b> if no priority was specified. | |
| 167 | * | |
| 168 | * @return the priority for newly created threads | |
| 169 | */ | |
| 170 | public final Integer getPriority() { | |
| 171 | 25 | return priority; |
| 172 | } | |
| 173 | ||
| 174 | /** | |
| 175 | * Returns the {@code UncaughtExceptionHandler} for the threads created by | |
| 176 | * this factory. Result can be <b>null</b> if no handler was provided. | |
| 177 | * | |
| 178 | * @return the {@code UncaughtExceptionHandler} | |
| 179 | */ | |
| 180 | public final Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { | |
| 181 | 25 | return uncaughtExceptionHandler; |
| 182 | } | |
| 183 | ||
| 184 | /** | |
| 185 | * Returns the number of threads this factory has already created. This | |
| 186 | * class maintains an internal counter that is incremented each time the | |
| 187 | * {@link #newThread(Runnable)} method is invoked. | |
| 188 | * | |
| 189 | * @return the number of threads created by this factory | |
| 190 | */ | |
| 191 | public long getThreadCount() { | |
| 192 | 12 | return threadCounter.get(); |
| 193 | } | |
| 194 | ||
| 195 | /** | |
| 196 | * Creates a new thread. This implementation delegates to the wrapped | |
| 197 | * factory for creating the thread. Then, on the newly created thread the | |
| 198 | * corresponding configuration options are set. | |
| 199 | * | |
| 200 | * @param r the {@code Runnable} to be executed by the new thread | |
| 201 | * @return the newly created thread | |
| 202 | */ | |
| 203 | @Override | |
| 204 | public Thread newThread(final Runnable r) { | |
| 205 | 21 | final Thread t = getWrappedFactory().newThread(r); |
| 206 | 21 | initializeThread(t); |
| 207 | ||
| 208 | 21 | return t; |
| 209 | } | |
| 210 | ||
| 211 | /** | |
| 212 | * Initializes the specified thread. This method is called by | |
| 213 | * {@link #newThread(Runnable)} after a new thread has been obtained from | |
| 214 | * the wrapped thread factory. It initializes the thread according to the | |
| 215 | * options set for this factory. | |
| 216 | * | |
| 217 | * @param t the thread to be initialized | |
| 218 | */ | |
| 219 | private void initializeThread(final Thread t) { | |
| 220 | ||
| 221 | 21 | if (getNamingPattern() != null) { |
| 222 | 12 | final Long count = Long.valueOf(threadCounter.incrementAndGet()); |
| 223 | 12 | t.setName(String.format(getNamingPattern(), count)); |
| 224 | } | |
| 225 | ||
| 226 | 21 | if (getUncaughtExceptionHandler() != null) { |
| 227 | 1 | t.setUncaughtExceptionHandler(getUncaughtExceptionHandler()); |
| 228 | } | |
| 229 | ||
| 230 | 21 | if (getPriority() != null) { |
| 231 | 1 | t.setPriority(getPriority().intValue()); |
| 232 | } | |
| 233 | ||
| 234 | 21 | if (getDaemonFlag() != null) { |
| 235 | 2 | t.setDaemon(getDaemonFlag().booleanValue()); |
| 236 | } | |
| 237 | 21 | } |
| 238 | ||
| 239 | /** | |
| 240 | * <p> | |
| 241 | * A <em>builder</em> class for creating instances of {@code | |
| 242 | * BasicThreadFactory}. | |
| 243 | * </p> | |
| 244 | * <p> | |
| 245 | * Using this builder class instances of {@code BasicThreadFactory} can be | |
| 246 | * created and initialized. The class provides methods that correspond to | |
| 247 | * the configuration options supported by {@code BasicThreadFactory}. Method | |
| 248 | * chaining is supported. Refer to the documentation of {@code | |
| 249 | * BasicThreadFactory} for a usage example. | |
| 250 | * </p> | |
| 251 | * | |
| 252 | * @version $Id: BasicThreadFactory.java 1436770 2013-01-22 07:09:45Z ggregory $ | |
| 253 | */ | |
| 254 | 90 | public static class Builder |
| 255 | implements org.apache.commons.lang3.builder.Builder<BasicThreadFactory> { | |
| 256 | ||
| 257 | /** The wrapped factory. */ | |
| 258 | private ThreadFactory wrappedFactory; | |
| 259 | ||
| 260 | /** The uncaught exception handler. */ | |
| 261 | private Thread.UncaughtExceptionHandler exceptionHandler; | |
| 262 | ||
| 263 | /** The naming pattern. */ | |
| 264 | private String namingPattern; | |
| 265 | ||
| 266 | /** The priority. */ | |
| 267 | private Integer priority; | |
| 268 | ||
| 269 | /** The daemon flag. */ | |
| 270 | private Boolean daemonFlag; | |
| 271 | ||
| 272 | /** | |
| 273 | * Sets the {@code ThreadFactory} to be wrapped by the new {@code | |
| 274 | * BasicThreadFactory}. | |
| 275 | * | |
| 276 | * @param factory the wrapped {@code ThreadFactory} (must not be | |
| 277 | * <b>null</b>) | |
| 278 | * @return a reference to this {@code Builder} | |
| 279 | * @throws NullPointerException if the passed in {@code ThreadFactory} | |
| 280 | * is <b>null</b> | |
| 281 | */ | |
| 282 | public Builder wrappedFactory(final ThreadFactory factory) { | |
| 283 | 12 | if (factory == null) { |
| 284 | 1 | throw new NullPointerException( |
| 285 | "Wrapped ThreadFactory must not be null!"); | |
| 286 | } | |
| 287 | ||
| 288 | 11 | wrappedFactory = factory; |
| 289 | 11 | return this; |
| 290 | } | |
| 291 | ||
| 292 | /** | |
| 293 | * Sets the naming pattern to be used by the new {@code | |
| 294 | * BasicThreadFactory}. | |
| 295 | * | |
| 296 | * @param pattern the naming pattern (must not be <b>null</b>) | |
| 297 | * @return a reference to this {@code Builder} | |
| 298 | * @throws NullPointerException if the naming pattern is <b>null</b> | |
| 299 | */ | |
| 300 | public Builder namingPattern(final String pattern) { | |
| 301 | 4 | if (pattern == null) { |
| 302 | 1 | throw new NullPointerException( |
| 303 | "Naming pattern must not be null!"); | |
| 304 | } | |
| 305 | ||
| 306 | 3 | namingPattern = pattern; |
| 307 | 3 | return this; |
| 308 | } | |
| 309 | ||
| 310 | /** | |
| 311 | * Sets the daemon flag for the new {@code BasicThreadFactory}. If this | |
| 312 | * flag is set to <b>true</b> the new thread factory will create daemon | |
| 313 | * threads. | |
| 314 | * | |
| 315 | * @param f the value of the daemon flag | |
| 316 | * @return a reference to this {@code Builder} | |
| 317 | */ | |
| 318 | public Builder daemon(final boolean f) { | |
| 319 | 4 | daemonFlag = Boolean.valueOf(f); |
| 320 | 4 | return this; |
| 321 | } | |
| 322 | ||
| 323 | /** | |
| 324 | * Sets the priority for the threads created by the new {@code | |
| 325 | * BasicThreadFactory}. | |
| 326 | * | |
| 327 | * @param prio the priority | |
| 328 | * @return a reference to this {@code Builder} | |
| 329 | */ | |
| 330 | public Builder priority(final int prio) { | |
| 331 | 2 | priority = Integer.valueOf(prio); |
| 332 | 2 | return this; |
| 333 | } | |
| 334 | ||
| 335 | /** | |
| 336 | * Sets the uncaught exception handler for the threads created by the | |
| 337 | * new {@code BasicThreadFactory}. | |
| 338 | * | |
| 339 | * @param handler the {@code UncaughtExceptionHandler} (must not be | |
| 340 | * <b>null</b>) | |
| 341 | * @return a reference to this {@code Builder} | |
| 342 | * @throws NullPointerException if the exception handler is <b>null</b> | |
| 343 | */ | |
| 344 | public Builder uncaughtExceptionHandler( | |
| 345 | final Thread.UncaughtExceptionHandler handler) { | |
| 346 | 3 | if (handler == null) { |
| 347 | 1 | throw new NullPointerException( |
| 348 | "Uncaught exception handler must not be null!"); | |
| 349 | } | |
| 350 | ||
| 351 | 2 | exceptionHandler = handler; |
| 352 | 2 | return this; |
| 353 | } | |
| 354 | ||
| 355 | /** | |
| 356 | * Resets this builder. All configuration options are set to default | |
| 357 | * values. Note: If the {@link #build()} method was called, it is not | |
| 358 | * necessary to call {@code reset()} explicitly because this is done | |
| 359 | * automatically. | |
| 360 | */ | |
| 361 | public void reset() { | |
| 362 | 14 | wrappedFactory = null; |
| 363 | 14 | exceptionHandler = null; |
| 364 | 14 | namingPattern = null; |
| 365 | 14 | priority = null; |
| 366 | 14 | daemonFlag = null; |
| 367 | 14 | } |
| 368 | ||
| 369 | /** | |
| 370 | * Creates a new {@code BasicThreadFactory} with all configuration | |
| 371 | * options that have been specified by calling methods on this builder. | |
| 372 | * After creating the factory {@link #reset()} is called. | |
| 373 | * | |
| 374 | * @return the new {@code BasicThreadFactory} | |
| 375 | */ | |
| 376 | @Override | |
| 377 | public BasicThreadFactory build() { | |
| 378 | 13 | final BasicThreadFactory factory = new BasicThreadFactory(this); |
| 379 | 13 | reset(); |
| 380 | 13 | return factory; |
| 381 | } | |
| 382 | } | |
| 383 | } |