1bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/*
2bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Copyright (C) 2006 Google Inc.
3bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
4bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Licensed under the Apache License, Version 2.0 (the "License");
5bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * you may not use this file except in compliance with the License.
6bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * You may obtain a copy of the License at
7bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
8bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * http://www.apache.org/licenses/LICENSE-2.0
9bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
10bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * Unless required by applicable law or agreed to in writing, software
11bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * distributed under the License is distributed on an "AS IS" BASIS,
12bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * See the License for the specific language governing permissions and
14bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * limitations under the License.
15bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */
16bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
17bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpackage com.google.common.util.concurrent;
18bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
19bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.concurrent.Executors;
20bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.concurrent.ThreadFactory;
21bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorimport java.util.concurrent.atomic.AtomicInteger;
22bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
23bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor/**
24bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * A ThreadFactory which decorates another ThreadFactory to set a name on
25bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * each thread created.
26bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor *
27bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @author Kevin Bourrillion
28bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor * @since 2009.09.15 <b>tentative</b>
29bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor */
30bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnorpublic class NamingThreadFactory implements ThreadFactory {
31bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private final ThreadFactory backingFactory;
32bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private final String format;
33bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private final AtomicInteger count = new AtomicInteger(0);
34bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
35bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public static final ThreadFactory DEFAULT_FACTORY
36bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor      = Executors.defaultThreadFactory();
37bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
38bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
39bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Creates a new factory that delegates to the default thread factory for
40bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * thread creation, then uses {@code format} to construct a name for the new
41bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * thread.
42bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
43bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param format a {@link String#format(String, Object...)}-compatible format
44bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     String, to which a unique integer (0, 1, etc.) will be supplied as the
45bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     single parameter. This integer will be unique to this instance of
46bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     NamingThreadFactory and will be assigned sequentially.
47bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
48bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public NamingThreadFactory(String format) {
49bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    this(format, DEFAULT_FACTORY);
50bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
51bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
52bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  /**
53bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * Creates a new factory that delegates to {@code backingFactory} for thread
54bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * creation, then uses {@code format} to construct a name for the new thread.
55bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *
56bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param format a {@link String#format(String, Object...)}-compatible format
57bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     String, to which a unique integer (0, 1, etc.) will be supplied as the
58bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   *     single parameter
59bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @param backingFactory the factory that will actually create the threads
60bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   * @throws java.util.IllegalFormatException if {@code format} is invalid
61bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor   */
62bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public NamingThreadFactory(String format, ThreadFactory backingFactory) {
63bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    this.format = format;
64bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    this.backingFactory = backingFactory;
65bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    makeName(0); // fail fast if format is bad
66bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
67bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
68bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  public Thread newThread(Runnable r) {
69bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    Thread t = backingFactory.newThread(r);
70bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    t.setName(makeName(count.getAndIncrement()));
71bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return t;
72bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
73bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor
74bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  private String makeName(int ordinal) {
75bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor    return String.format(format, ordinal);
76bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor  }
77bfe2dd089341dcb4c1fb65a5b6b077ad0ebbf6dcDan Egnor}
78