/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.lang3.concurrent;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.lang3.Validate;

An implementation of the ThreadFactory interface that provides some configuration options for the threads it creates.

A ThreadFactory is used for instance by an ExecutorService to create the threads it uses for executing tasks. In many cases users do not have to care about a ThreadFactory because the default one used by an ExecutorService will do. However, if there are special requirements for the threads, a custom ThreadFactory has to be created.

This class provides some frequently needed configuration options for the threads it creates. These are the following:

  • A name pattern for the threads created by this factory can be specified. This is often useful if an application uses multiple executor services for different purposes. If the names of the threads used by these services have meaningful names, log output or exception traces can be much easier to read. Naming patterns are format strings as used by the String.format() method. The string can contain the place holder %d which will be replaced by the number of the current thread ( ThreadFactoryImpl keeps a counter of the threads it has already created). For instance, the naming pattern "My %d. worker thread" will result in thread names like "My 1. worker thread", "My 2. worker thread" and so on.
  • A flag whether the threads created by this factory should be daemon threads. This can impact the exit behavior of the current Java application because the JVM shuts down if there are only daemon threads running.
  • The priority of the thread. Here an integer value can be provided. The java.lang.Thread class defines constants for valid ranges of priority values.
  • The UncaughtExceptionHandler for the thread. This handler is called if an uncaught exception occurs within the thread.

BasicThreadFactory wraps another thread factory which actually creates new threads. The configuration options are set on the threads created by the wrapped thread factory. On construction time the factory to be wrapped can be specified. If none is provided, a default ThreadFactory is used.

Instances of BasicThreadFactory are not created directly, but the nested Builder class is used for this purpose. Using the builder only the configuration options an application is interested in need to be set. The following example shows how a BasicThreadFactory is created and installed in an ExecutorService:

// Create a factory that produces daemon threads with a naming pattern and
// a priority
BasicThreadFactory factory = new BasicThreadFactory.Builder()
    .namingPattern("workerthread-%d")
    .daemon(true)
    .priority(Thread.MAX_PRIORITY)
    .build();
// Create an executor service for single-threaded execution
ExecutorService exec = Executors.newSingleThreadExecutor(factory);
Since:3.0
/** * <p> * An implementation of the {@code ThreadFactory} interface that provides some * configuration options for the threads it creates. * </p> * <p> * A {@code ThreadFactory} is used for instance by an {@code ExecutorService} to * create the threads it uses for executing tasks. In many cases users do not * have to care about a {@code ThreadFactory} because the default one used by an * {@code ExecutorService} will do. However, if there are special requirements * for the threads, a custom {@code ThreadFactory} has to be created. * </p> * <p> * This class provides some frequently needed configuration options for the * threads it creates. These are the following: * </p> * <ul> * <li>A name pattern for the threads created by this factory can be specified. * This is often useful if an application uses multiple executor services for * different purposes. If the names of the threads used by these services have * meaningful names, log output or exception traces can be much easier to read. * Naming patterns are <em>format strings</em> as used by the {@code * String.format()} method. The string can contain the place holder {@code %d} * which will be replaced by the number of the current thread ({@code * ThreadFactoryImpl} keeps a counter of the threads it has already created). * For instance, the naming pattern {@code "My %d. worker thread"} will result * in thread names like {@code "My 1. worker thread"}, {@code * "My 2. worker thread"} and so on.</li> * <li>A flag whether the threads created by this factory should be daemon * threads. This can impact the exit behavior of the current Java application * because the JVM shuts down if there are only daemon threads running.</li> * <li>The priority of the thread. Here an integer value can be provided. The * {@code java.lang.Thread} class defines constants for valid ranges of priority * values.</li> * <li>The {@code UncaughtExceptionHandler} for the thread. This handler is * called if an uncaught exception occurs within the thread.</li> * </ul> * <p> * {@code BasicThreadFactory} wraps another thread factory which actually * creates new threads. The configuration options are set on the threads created * by the wrapped thread factory. On construction time the factory to be wrapped * can be specified. If none is provided, a default {@code ThreadFactory} is * used. * </p> * <p> * Instances of {@code BasicThreadFactory} are not created directly, but the * nested {@code Builder} class is used for this purpose. Using the builder only * the configuration options an application is interested in need to be set. The * following example shows how a {@code BasicThreadFactory} is created and * installed in an {@code ExecutorService}: * </p> * * <pre> * // Create a factory that produces daemon threads with a naming pattern and * // a priority * BasicThreadFactory factory = new BasicThreadFactory.Builder() * .namingPattern(&quot;workerthread-%d&quot;) * .daemon(true) * .priority(Thread.MAX_PRIORITY) * .build(); * // Create an executor service for single-threaded execution * ExecutorService exec = Executors.newSingleThreadExecutor(factory); * </pre> * * @since 3.0 */
public class BasicThreadFactory implements ThreadFactory {
A counter for the threads created by this factory.
/** A counter for the threads created by this factory. */
private final AtomicLong threadCounter;
Stores the wrapped factory.
/** Stores the wrapped factory. */
private final ThreadFactory wrappedFactory;
Stores the uncaught exception handler.
/** Stores the uncaught exception handler. */
private final Thread.UncaughtExceptionHandler uncaughtExceptionHandler;
Stores the naming pattern for newly created threads.
/** Stores the naming pattern for newly created threads. */
private final String namingPattern;
Stores the priority.
/** Stores the priority. */
private final Integer priority;
Stores the daemon status flag.
/** Stores the daemon status flag. */
private final Boolean daemon;
Creates a new instance of ThreadFactoryImpl and configures it from the specified Builder object.
Params:
  • builder – the Builder object
/** * Creates a new instance of {@code ThreadFactoryImpl} and configures it * from the specified {@code Builder} object. * * @param builder the {@code Builder} object */
private BasicThreadFactory(final Builder builder) { if (builder.wrappedFactory == null) { wrappedFactory = Executors.defaultThreadFactory(); } else { wrappedFactory = builder.wrappedFactory; } namingPattern = builder.namingPattern; priority = builder.priority; daemon = builder.daemon; uncaughtExceptionHandler = builder.exceptionHandler; threadCounter = new AtomicLong(); }
Returns the wrapped ThreadFactory. This factory is used for actually creating threads. This method never returns null. If no ThreadFactory was passed when this object was created, a default thread factory is returned.
Returns:the wrapped ThreadFactory
/** * Returns the wrapped {@code ThreadFactory}. This factory is used for * actually creating threads. This method never returns <b>null</b>. If no * {@code ThreadFactory} was passed when this object was created, a default * thread factory is returned. * * @return the wrapped {@code ThreadFactory} */
public final ThreadFactory getWrappedFactory() { return wrappedFactory; }
Returns the naming pattern for naming newly created threads. Result can be null if no naming pattern was provided.
Returns:the naming pattern
/** * Returns the naming pattern for naming newly created threads. Result can * be <b>null</b> if no naming pattern was provided. * * @return the naming pattern */
public final String getNamingPattern() { return namingPattern; }
Returns the daemon flag. This flag determines whether newly created threads should be daemon threads. If true, this factory object calls setDaemon(true) on the newly created threads. Result can be null if no daemon flag was provided at creation time.
Returns:the daemon flag
/** * Returns the daemon flag. This flag determines whether newly created * threads should be daemon threads. If <b>true</b>, this factory object * calls {@code setDaemon(true)} on the newly created threads. Result can be * <b>null</b> if no daemon flag was provided at creation time. * * @return the daemon flag */
public final Boolean getDaemonFlag() { return daemon; }
Returns the priority of the threads created by this factory. Result can be null if no priority was specified.
Returns:the priority for newly created threads
/** * Returns the priority of the threads created by this factory. Result can * be <b>null</b> if no priority was specified. * * @return the priority for newly created threads */
public final Integer getPriority() { return priority; }
Returns the UncaughtExceptionHandler for the threads created by this factory. Result can be null if no handler was provided.
Returns:the UncaughtExceptionHandler
/** * Returns the {@code UncaughtExceptionHandler} for the threads created by * this factory. Result can be <b>null</b> if no handler was provided. * * @return the {@code UncaughtExceptionHandler} */
public final Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { return uncaughtExceptionHandler; }
Returns the number of threads this factory has already created. This class maintains an internal counter that is incremented each time the newThread(Runnable) method is invoked.
Returns:the number of threads created by this factory
/** * Returns the number of threads this factory has already created. This * class maintains an internal counter that is incremented each time the * {@link #newThread(Runnable)} method is invoked. * * @return the number of threads created by this factory */
public long getThreadCount() { return threadCounter.get(); }
Creates a new thread. This implementation delegates to the wrapped factory for creating the thread. Then, on the newly created thread the corresponding configuration options are set.
Params:
  • runnable – the Runnable to be executed by the new thread
Returns:the newly created thread
/** * Creates a new thread. This implementation delegates to the wrapped * factory for creating the thread. Then, on the newly created thread the * corresponding configuration options are set. * * @param runnable the {@code Runnable} to be executed by the new thread * @return the newly created thread */
@Override public Thread newThread(final Runnable runnable) { final Thread thread = getWrappedFactory().newThread(runnable); initializeThread(thread); return thread; }
Initializes the specified thread. This method is called by newThread(Runnable) after a new thread has been obtained from the wrapped thread factory. It initializes the thread according to the options set for this factory.
Params:
  • thread – the thread to be initialized
/** * Initializes the specified thread. This method is called by * {@link #newThread(Runnable)} after a new thread has been obtained from * the wrapped thread factory. It initializes the thread according to the * options set for this factory. * * @param thread the thread to be initialized */
private void initializeThread(final Thread thread) { if (getNamingPattern() != null) { final Long count = Long.valueOf(threadCounter.incrementAndGet()); thread.setName(String.format(getNamingPattern(), count)); } if (getUncaughtExceptionHandler() != null) { thread.setUncaughtExceptionHandler(getUncaughtExceptionHandler()); } if (getPriority() != null) { thread.setPriority(getPriority().intValue()); } if (getDaemonFlag() != null) { thread.setDaemon(getDaemonFlag().booleanValue()); } }

A builder class for creating instances of BasicThreadFactory.

Using this builder class instances of BasicThreadFactory can be created and initialized. The class provides methods that correspond to the configuration options supported by BasicThreadFactory. Method chaining is supported. Refer to the documentation of BasicThreadFactory for a usage example.

/** * <p> * A <em>builder</em> class for creating instances of {@code * BasicThreadFactory}. * </p> * <p> * Using this builder class instances of {@code BasicThreadFactory} can be * created and initialized. The class provides methods that correspond to * the configuration options supported by {@code BasicThreadFactory}. Method * chaining is supported. Refer to the documentation of {@code * BasicThreadFactory} for a usage example. * </p> * */
public static class Builder implements org.apache.commons.lang3.builder.Builder<BasicThreadFactory> {
The wrapped factory.
/** The wrapped factory. */
private ThreadFactory wrappedFactory;
The uncaught exception handler.
/** The uncaught exception handler. */
private Thread.UncaughtExceptionHandler exceptionHandler;
The naming pattern.
/** The naming pattern. */
private String namingPattern;
The priority.
/** The priority. */
private Integer priority;
The daemon flag.
/** The daemon flag. */
private Boolean daemon;
Sets the ThreadFactory to be wrapped by the new BasicThreadFactory.
Params:
  • factory – the wrapped ThreadFactory (must not be null)
Throws:
Returns:a reference to this Builder
/** * Sets the {@code ThreadFactory} to be wrapped by the new {@code * BasicThreadFactory}. * * @param factory the wrapped {@code ThreadFactory} (must not be * <b>null</b>) * @return a reference to this {@code Builder} * @throws NullPointerException if the passed in {@code ThreadFactory} * is <b>null</b> */
public Builder wrappedFactory(final ThreadFactory factory) { Validate.notNull(factory, "Wrapped ThreadFactory must not be null!"); wrappedFactory = factory; return this; }
Sets the naming pattern to be used by the new BasicThreadFactory.
Params:
  • pattern – the naming pattern (must not be null)
Throws:
Returns:a reference to this Builder
/** * Sets the naming pattern to be used by the new {@code * BasicThreadFactory}. * * @param pattern the naming pattern (must not be <b>null</b>) * @return a reference to this {@code Builder} * @throws NullPointerException if the naming pattern is <b>null</b> */
public Builder namingPattern(final String pattern) { Validate.notNull(pattern, "Naming pattern must not be null!"); namingPattern = pattern; return this; }
Sets the daemon flag for the new BasicThreadFactory. If this flag is set to true the new thread factory will create daemon threads.
Params:
  • daemon – the value of the daemon flag
Returns:a reference to this Builder
/** * Sets the daemon flag for the new {@code BasicThreadFactory}. If this * flag is set to <b>true</b> the new thread factory will create daemon * threads. * * @param daemon the value of the daemon flag * @return a reference to this {@code Builder} */
public Builder daemon(final boolean daemon) { this.daemon = Boolean.valueOf(daemon); return this; }
Sets the priority for the threads created by the new BasicThreadFactory.
Params:
  • priority – the priority
Returns:a reference to this Builder
/** * Sets the priority for the threads created by the new {@code * BasicThreadFactory}. * * @param priority the priority * @return a reference to this {@code Builder} */
public Builder priority(final int priority) { this.priority = Integer.valueOf(priority); return this; }
Sets the uncaught exception handler for the threads created by the new BasicThreadFactory.
Params:
  • handler – the UncaughtExceptionHandler (must not be null)
Throws:
Returns:a reference to this Builder
/** * Sets the uncaught exception handler for the threads created by the * new {@code BasicThreadFactory}. * * @param handler the {@code UncaughtExceptionHandler} (must not be * <b>null</b>) * @return a reference to this {@code Builder} * @throws NullPointerException if the exception handler is <b>null</b> */
public Builder uncaughtExceptionHandler( final Thread.UncaughtExceptionHandler handler) { Validate.notNull(handler, "Uncaught exception handler must not be null!"); exceptionHandler = handler; return this; }
Resets this builder. All configuration options are set to default values. Note: If the build() method was called, it is not necessary to call reset() explicitly because this is done automatically.
/** * Resets this builder. All configuration options are set to default * values. Note: If the {@link #build()} method was called, it is not * necessary to call {@code reset()} explicitly because this is done * automatically. */
public void reset() { wrappedFactory = null; exceptionHandler = null; namingPattern = null; priority = null; daemon = null; }
Creates a new BasicThreadFactory with all configuration options that have been specified by calling methods on this builder. After creating the factory reset() is called.
Returns:the new BasicThreadFactory
/** * Creates a new {@code BasicThreadFactory} with all configuration * options that have been specified by calling methods on this builder. * After creating the factory {@link #reset()} is called. * * @return the new {@code BasicThreadFactory} */
@Override public BasicThreadFactory build() { final BasicThreadFactory factory = new BasicThreadFactory(this); reset(); return factory; } } }