Coverage Summary for Class: ThreadFactoryBuilder (com.google.common.util.concurrent)

Class Method, % Line, %
ThreadFactoryBuilder 0% (0/10) 0% (0/30)
ThreadFactoryBuilder$1 0% (0/2) 0% (0/11)
Total 0% (0/12) 0% (0/41)


1 /* 2  * Copyright (C) 2010 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.util.concurrent; 16  17 import static com.google.common.base.Preconditions.checkArgument; 18 import static com.google.common.base.Preconditions.checkNotNull; 19 import static java.util.Objects.requireNonNull; 20  21 import com.google.common.annotations.GwtIncompatible; 22 import com.google.errorprone.annotations.CanIgnoreReturnValue; 23 import com.google.errorprone.annotations.CheckReturnValue; 24 import java.lang.Thread.UncaughtExceptionHandler; 25 import java.util.Locale; 26 import java.util.concurrent.Executors; 27 import java.util.concurrent.ThreadFactory; 28 import java.util.concurrent.atomic.AtomicLong; 29 import javax.annotation.CheckForNull; 30  31 /** 32  * A ThreadFactory builder, providing any combination of these features: 33  * 34  * <ul> 35  * <li>whether threads should be marked as {@linkplain Thread#setDaemon daemon} threads 36  * <li>a {@linkplain ThreadFactoryBuilder#setNameFormat naming format} 37  * <li>a {@linkplain Thread#setPriority thread priority} 38  * <li>an {@linkplain Thread#setUncaughtExceptionHandler uncaught exception handler} 39  * <li>a {@linkplain ThreadFactory#newThread backing thread factory} 40  * </ul> 41  * 42  * <p>If no backing thread factory is provided, a default backing thread factory is used as if by 43  * calling {@code setThreadFactory(}{@link Executors#defaultThreadFactory()}{@code )}. 44  * 45  * @author Kurt Alfred Kluever 46  * @since 4.0 47  */ 48 @CanIgnoreReturnValue 49 @GwtIncompatible 50 @ElementTypesAreNonnullByDefault 51 public final class ThreadFactoryBuilder { 52  @CheckForNull private String nameFormat = null; 53  @CheckForNull private Boolean daemon = null; 54  @CheckForNull private Integer priority = null; 55  @CheckForNull private UncaughtExceptionHandler uncaughtExceptionHandler = null; 56  @CheckForNull private ThreadFactory backingThreadFactory = null; 57  58  /** Creates a new {@link ThreadFactory} builder. */ 59  public ThreadFactoryBuilder() {} 60  61  /** 62  * Sets the naming format to use when naming threads ({@link Thread#setName}) which are created 63  * with this ThreadFactory. 64  * 65  * @param nameFormat a {@link String#format(String, Object...)}-compatible format String, to which 66  * a unique integer (0, 1, etc.) will be supplied as the single parameter. This integer will 67  * be unique to the built instance of the ThreadFactory and will be assigned sequentially. For 68  * example, {@code "rpc-pool-%d"} will generate thread names like {@code "rpc-pool-0"}, {@code 69  * "rpc-pool-1"}, {@code "rpc-pool-2"}, etc. 70  * @return this for the builder pattern 71  */ 72  public ThreadFactoryBuilder setNameFormat(String nameFormat) { 73  String unused = format(nameFormat, 0); // fail fast if the format is bad or null 74  this.nameFormat = nameFormat; 75  return this; 76  } 77  78  /** 79  * Sets daemon or not for new threads created with this ThreadFactory. 80  * 81  * @param daemon whether or not new Threads created with this ThreadFactory will be daemon threads 82  * @return this for the builder pattern 83  */ 84  public ThreadFactoryBuilder setDaemon(boolean daemon) { 85  this.daemon = daemon; 86  return this; 87  } 88  89  /** 90  * Sets the priority for new threads created with this ThreadFactory. 91  * 92  * @param priority the priority for new Threads created with this ThreadFactory 93  * @return this for the builder pattern 94  */ 95  public ThreadFactoryBuilder setPriority(int priority) { 96  // Thread#setPriority() already checks for validity. These error messages 97  // are nicer though and will fail-fast. 98  checkArgument( 99  priority >= Thread.MIN_PRIORITY, 100  "Thread priority (%s) must be >= %s", 101  priority, 102  Thread.MIN_PRIORITY); 103  checkArgument( 104  priority <= Thread.MAX_PRIORITY, 105  "Thread priority (%s) must be <= %s", 106  priority, 107  Thread.MAX_PRIORITY); 108  this.priority = priority; 109  return this; 110  } 111  112  /** 113  * Sets the {@link UncaughtExceptionHandler} for new threads created with this ThreadFactory. 114  * 115  * @param uncaughtExceptionHandler the uncaught exception handler for new Threads created with 116  * this ThreadFactory 117  * @return this for the builder pattern 118  */ 119  public ThreadFactoryBuilder setUncaughtExceptionHandler( 120  UncaughtExceptionHandler uncaughtExceptionHandler) { 121  this.uncaughtExceptionHandler = checkNotNull(uncaughtExceptionHandler); 122  return this; 123  } 124  125  /** 126  * Sets the backing {@link ThreadFactory} for new threads created with this ThreadFactory. Threads 127  * will be created by invoking #newThread(Runnable) on this backing {@link ThreadFactory}. 128  * 129  * @param backingThreadFactory the backing {@link ThreadFactory} which will be delegated to during 130  * thread creation. 131  * @return this for the builder pattern 132  * @see MoreExecutors 133  */ 134  public ThreadFactoryBuilder setThreadFactory(ThreadFactory backingThreadFactory) { 135  this.backingThreadFactory = checkNotNull(backingThreadFactory); 136  return this; 137  } 138  139  /** 140  * Returns a new thread factory using the options supplied during the building process. After 141  * building, it is still possible to change the options used to build the ThreadFactory and/or 142  * build again. State is not shared amongst built instances. 143  * 144  * @return the fully constructed {@link ThreadFactory} 145  */ 146  @CheckReturnValue 147  public ThreadFactory build() { 148  return doBuild(this); 149  } 150  151  // Split out so that the anonymous ThreadFactory can't contain a reference back to the builder. 152  // At least, I assume that's why. TODO(cpovirk): Check, and maybe add a test for this. 153  private static ThreadFactory doBuild(ThreadFactoryBuilder builder) { 154  final String nameFormat = builder.nameFormat; 155  final Boolean daemon = builder.daemon; 156  final Integer priority = builder.priority; 157  final UncaughtExceptionHandler uncaughtExceptionHandler = builder.uncaughtExceptionHandler; 158  final ThreadFactory backingThreadFactory = 159  (builder.backingThreadFactory != null) 160  ? builder.backingThreadFactory 161  : Executors.defaultThreadFactory(); 162  final AtomicLong count = (nameFormat != null) ? new AtomicLong(0) : null; 163  return new ThreadFactory() { 164  @Override 165  public Thread newThread(Runnable runnable) { 166  Thread thread = backingThreadFactory.newThread(runnable); 167  if (nameFormat != null) { 168  // requireNonNull is safe because we create `count` if (and only if) we have a nameFormat. 169  thread.setName(format(nameFormat, requireNonNull(count).getAndIncrement())); 170  } 171  if (daemon != null) { 172  thread.setDaemon(daemon); 173  } 174  if (priority != null) { 175  thread.setPriority(priority); 176  } 177  if (uncaughtExceptionHandler != null) { 178  thread.setUncaughtExceptionHandler(uncaughtExceptionHandler); 179  } 180  return thread; 181  } 182  }; 183  } 184  185  private static String format(String format, Object... args) { 186  return String.format(Locale.ROOT, format, args); 187  } 188 }