All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.hengyunabc.metrics.ThreadFactoryBuilder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2010 The Guava Authors
 *
 * Licensed 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 io.github.hengyunabc.metrics;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;

/**
 * From google guava.
 * A ThreadFactory builder, providing any combination of these features:
 * 
    *
  • whether threads should be marked as {@linkplain Thread#setDaemon daemon} * threads *
  • a {@linkplain ThreadFactoryBuilder#setNameFormat naming format} *
  • a {@linkplain Thread#setPriority thread priority} *
  • an {@linkplain Thread#setUncaughtExceptionHandler uncaught exception * handler} *
  • a {@linkplain ThreadFactory#newThread backing thread factory} *
*

* If no backing thread factory is provided, a default backing thread factory is * used as if by calling {@code setThreadFactory(} * {@link Executors#defaultThreadFactory()}{@code )}. * * @author Kurt Alfred Kluever * @since 4.0 */ public final class ThreadFactoryBuilder { private String nameFormat = null; private Boolean daemon = null; private Integer priority = null; private UncaughtExceptionHandler uncaughtExceptionHandler = null; private ThreadFactory backingThreadFactory = null; /** * Creates a new {@link ThreadFactory} builder. */ public ThreadFactoryBuilder() { } /** * Sets the naming format to use when naming threads ({@link Thread#setName} * ) which are created with this ThreadFactory. * * @param nameFormat * a {@link String#format(String, Object...)}-compatible format * String, to which a unique integer (0, 1, etc.) will be * supplied as the single parameter. This integer will be unique * to the built instance of the ThreadFactory and will be * assigned sequentially. For example, {@code "rpc-pool-%d"} will * generate thread names like {@code "rpc-pool-0"}, * {@code "rpc-pool-1"}, {@code "rpc-pool-2"}, etc. * @return this for the builder pattern */ public ThreadFactoryBuilder setNameFormat(String nameFormat) { String.format(nameFormat, 0); // fail fast if the format is bad or null this.nameFormat = nameFormat; return this; } /** * Sets daemon or not for new threads created with this ThreadFactory. * * @param daemon * whether or not new Threads created with this ThreadFactory * will be daemon threads * @return this for the builder pattern */ public ThreadFactoryBuilder setDaemon(boolean daemon) { this.daemon = daemon; return this; } /** * Sets the priority for new threads created with this ThreadFactory. * * @param priority * the priority for new Threads created with this ThreadFactory * @return this for the builder pattern */ public ThreadFactoryBuilder setPriority(int priority) { // Thread#setPriority() already checks for validity. These error // messages // are nicer though and will fail-fast. checkArgument(priority >= Thread.MIN_PRIORITY, "Thread priority (%s) must be >= %s", priority, Thread.MIN_PRIORITY); checkArgument(priority <= Thread.MAX_PRIORITY, "Thread priority (%s) must be <= %s", priority, Thread.MAX_PRIORITY); this.priority = priority; return this; } /** * Sets the {@link UncaughtExceptionHandler} for new threads created with * this ThreadFactory. * * @param uncaughtExceptionHandler * the uncaught exception handler for new Threads created with * this ThreadFactory * @return this for the builder pattern */ public ThreadFactoryBuilder setUncaughtExceptionHandler(UncaughtExceptionHandler uncaughtExceptionHandler) { this.uncaughtExceptionHandler = checkNotNull(uncaughtExceptionHandler); return this; } /** * Sets the backing {@link ThreadFactory} for new threads created with this * ThreadFactory. Threads will be created by invoking #newThread(Runnable) * on this backing {@link ThreadFactory}. * * @param backingThreadFactory * the backing {@link ThreadFactory} which will be delegated to * during thread creation. * @return this for the builder pattern */ public ThreadFactoryBuilder setThreadFactory(ThreadFactory backingThreadFactory) { this.backingThreadFactory = checkNotNull(backingThreadFactory); return this; } /** * Returns a new thread factory using the options supplied during the * building process. After building, it is still possible to change the * options used to build the ThreadFactory and/or build again. State is not * shared amongst built instances. * * @return the fully constructed {@link ThreadFactory} */ public ThreadFactory build() { return build(this); } private static ThreadFactory build(ThreadFactoryBuilder builder) { final String nameFormat = builder.nameFormat; final Boolean daemon = builder.daemon; final Integer priority = builder.priority; final UncaughtExceptionHandler uncaughtExceptionHandler = builder.uncaughtExceptionHandler; final ThreadFactory backingThreadFactory = (builder.backingThreadFactory != null) ? builder.backingThreadFactory : Executors.defaultThreadFactory(); final AtomicLong count = (nameFormat != null) ? new AtomicLong(0) : null; return new ThreadFactory() { @Override public Thread newThread(Runnable runnable) { Thread thread = backingThreadFactory.newThread(runnable); if (nameFormat != null) { thread.setName(String.format(nameFormat, count.getAndIncrement())); } if (daemon != null) { thread.setDaemon(daemon); } if (priority != null) { thread.setPriority(priority); } if (uncaughtExceptionHandler != null) { thread.setUncaughtExceptionHandler(uncaughtExceptionHandler); } return thread; } }; } /** * Substitutes each {@code %s} in {@code template} with an argument. These * are matched by position: the first {@code %s} gets {@code args[0]}, etc. * If there are more arguments than placeholders, the unmatched arguments * will be appended to the end of the formatted message in square braces. * * @param template * a non-null string containing 0 or more {@code %s} * placeholders. * @param args * the arguments to be substituted into the message template. * Arguments are converted to strings using * {@link String#valueOf(Object)}. Arguments can be null. */ // Note that this is somewhat-improperly used from Verify.java as well. static String format(String template, Object... args) { template = String.valueOf(template); // null -> "null" // start substituting the arguments into the '%s' placeholders StringBuilder builder = new StringBuilder(template.length() + 16 * args.length); int templateStart = 0; int i = 0; while (i < args.length) { int placeholderStart = template.indexOf("%s", templateStart); if (placeholderStart == -1) { break; } builder.append(template.substring(templateStart, placeholderStart)); builder.append(args[i++]); templateStart = placeholderStart + 2; } builder.append(template.substring(templateStart)); // if we run out of placeholders, append the extra args in square braces if (i < args.length) { builder.append(" ["); builder.append(args[i++]); while (i < args.length) { builder.append(", "); builder.append(args[i++]); } builder.append(']'); } return builder.toString(); } /** * Ensures the truth of an expression involving one or more parameters to * the calling method. * * @param expression * a boolean expression * @param errorMessageTemplate * a template for the exception message should the check fail. * The message is formed by replacing each {@code %s} placeholder * in the template with an argument. These are matched by * position - the first {@code %s} gets * {@code errorMessageArgs[0]}, etc. Unmatched arguments will be * appended to the formatted message in square braces. Unmatched * placeholders will be left as-is. * @param errorMessageArgs * the arguments to be substituted into the message template. * Arguments are converted to strings using * {@link String#valueOf(Object)}. * @throws IllegalArgumentException * if {@code expression} is false * @throws NullPointerException * if the check fails and either {@code errorMessageTemplate} or * {@code errorMessageArgs} is null (don't let this happen) */ private void checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) { if (!expression) { throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs)); } } /** * Ensures that an object reference passed as a parameter to the calling * method is not null. * * @param reference * an object reference * @return the non-null reference that was validated * @throws NullPointerException * if {@code reference} is null */ public static T checkNotNull(T reference) { if (reference == null) { throw new NullPointerException(); } return reference; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy