View Javadoc
1   /*
2    * Copyright 2013 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  
17  package io.netty.util.concurrent;
18  
19  import io.netty.util.internal.StringUtil;
20  
21  import java.util.Locale;
22  import java.util.concurrent.ThreadFactory;
23  import java.util.concurrent.atomic.AtomicInteger;
24  
25  /**
26   * A {@link ThreadFactory} implementation with a simple naming rule.
27   */
28  public class DefaultThreadFactory implements ThreadFactory {
29  
30      private static final AtomicInteger poolId = new AtomicInteger();
31  
32      private final AtomicInteger nextId = new AtomicInteger();
33      private final String prefix;
34      private final boolean daemon;
35      private final int priority;
36  
37      public DefaultThreadFactory(Class<?> poolType) {
38          this(poolType, false, Thread.NORM_PRIORITY);
39      }
40  
41      public DefaultThreadFactory(String poolName) {
42          this(poolName, false, Thread.NORM_PRIORITY);
43      }
44  
45      public DefaultThreadFactory(Class<?> poolType, boolean daemon) {
46          this(poolType, daemon, Thread.NORM_PRIORITY);
47      }
48  
49      public DefaultThreadFactory(String poolName, boolean daemon) {
50          this(poolName, daemon, Thread.NORM_PRIORITY);
51      }
52  
53      public DefaultThreadFactory(Class<?> poolType, int priority) {
54          this(poolType, false, priority);
55      }
56  
57      public DefaultThreadFactory(String poolName, int priority) {
58          this(poolName, false, priority);
59      }
60  
61      public DefaultThreadFactory(Class<?> poolType, boolean daemon, int priority) {
62          this(toPoolName(poolType), daemon, priority);
63      }
64  
65      private static String toPoolName(Class<?> poolType) {
66          if (poolType == null) {
67              throw new NullPointerException("poolType");
68          }
69  
70          String poolName = StringUtil.simpleClassName(poolType);
71          switch (poolName.length()) {
72              case 0:
73                  return "unknown";
74              case 1:
75                  return poolName.toLowerCase(Locale.US);
76              default:
77                  if (Character.isUpperCase(poolName.charAt(0)) && Character.isLowerCase(poolName.charAt(1))) {
78                      return Character.toLowerCase(poolName.charAt(0)) + poolName.substring(1);
79                  } else {
80                      return poolName;
81                  }
82          }
83      }
84  
85      public DefaultThreadFactory(String poolName, boolean daemon, int priority) {
86          if (poolName == null) {
87              throw new NullPointerException("poolName");
88          }
89          if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
90              throw new IllegalArgumentException(
91                      "priority: " + priority + " (expected: Thread.MIN_PRIORITY <= priority <= Thread.MAX_PRIORITY)");
92          }
93  
94          prefix = poolName + '-' + poolId.incrementAndGet() + '-';
95          this.daemon = daemon;
96          this.priority = priority;
97      }
98  
99      @Override
100     public Thread newThread(Runnable r) {
101         Thread t = newThread(new DefaultRunnableDecorator(r), prefix + nextId.incrementAndGet());
102         try {
103             if (t.isDaemon()) {
104                 if (!daemon) {
105                     t.setDaemon(false);
106                 }
107             } else {
108                 if (daemon) {
109                     t.setDaemon(true);
110                 }
111             }
112 
113             if (t.getPriority() != priority) {
114                 t.setPriority(priority);
115             }
116         } catch (Exception ignored) {
117             // Doesn't matter even if failed to set.
118         }
119         return t;
120     }
121 
122     protected Thread newThread(Runnable r, String name) {
123         return new FastThreadLocalThread(r, name);
124     }
125 
126     private static final class DefaultRunnableDecorator implements Runnable {
127 
128         private final Runnable r;
129 
130         DefaultRunnableDecorator(Runnable r) {
131             this.r = r;
132         }
133 
134         @Override
135         public void run() {
136             try {
137                 r.run();
138             } finally {
139                 FastThreadLocal.removeAll();
140             }
141         }
142     }
143 }