1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package com.baidu.fsg.uid.utils;
17
18 import java.lang.Thread.UncaughtExceptionHandler;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ThreadFactory;
21 import java.util.concurrent.atomic.AtomicLong;
22
23 import org.apache.commons.lang.ClassUtils;
24 import org.apache.commons.lang.StringUtils;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28
29
30
31
32
33
34 public class NamingThreadFactory implements ThreadFactory {
35 private static final Logger LOGGER = LoggerFactory.getLogger(NamingThreadFactory.class);
36
37
38
39
40 private String name;
41
42
43
44 private boolean daemon;
45
46
47
48 private UncaughtExceptionHandler uncaughtExceptionHandler;
49
50
51
52 private final ConcurrentHashMap<String, AtomicLong> sequences;
53
54
55
56
57 public NamingThreadFactory() {
58 this(null, false, null);
59 }
60
61 public NamingThreadFactory(String name) {
62 this(name, false, null);
63 }
64
65 public NamingThreadFactory(String name, boolean daemon) {
66 this(name, daemon, null);
67 }
68
69 public NamingThreadFactory(String name, boolean daemon, UncaughtExceptionHandler handler) {
70 this.name = name;
71 this.daemon = daemon;
72 this.uncaughtExceptionHandler = handler;
73 this.sequences = new ConcurrentHashMap<String, AtomicLong>();
74 }
75
76 @Override
77 public Thread newThread(Runnable r) {
78 Thread thread = new Thread(r);
79 thread.setDaemon(this.daemon);
80
81
82
83 String prefix = this.name;
84 if (StringUtils.isBlank(prefix)) {
85 prefix = getInvoker(2);
86 }
87 thread.setName(prefix + "-" + getSequence(prefix));
88
89
90 if (this.uncaughtExceptionHandler != null) {
91 thread.setUncaughtExceptionHandler(this.uncaughtExceptionHandler);
92 } else {
93 thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
94 public void uncaughtException(Thread t, Throwable e) {
95 LOGGER.error("unhandled exception in thread: " + t.getId() + ":" + t.getName(), e);
96 }
97 });
98 }
99
100 return thread;
101 }
102
103
104
105
106
107
108
109 private String getInvoker(int depth) {
110 Exception e = new Exception();
111 StackTraceElement[] stes = e.getStackTrace();
112 if (stes.length > depth) {
113 return ClassUtils.getShortClassName(stes[depth].getClassName());
114 }
115 return getClass().getSimpleName();
116 }
117
118
119
120
121
122
123
124 private long getSequence(String invoker) {
125 AtomicLong r = this.sequences.get(invoker);
126 if (r == null) {
127 r = new AtomicLong(0);
128 AtomicLong previous = this.sequences.putIfAbsent(invoker, r);
129 if (previous != null) {
130 r = previous;
131 }
132 }
133
134 return r.incrementAndGet();
135 }
136
137
138
139
140 public String getName() {
141 return name;
142 }
143
144 public void setName(String name) {
145 this.name = name;
146 }
147
148 public boolean isDaemon() {
149 return daemon;
150 }
151
152 public void setDaemon(boolean daemon) {
153 this.daemon = daemon;
154 }
155
156 public UncaughtExceptionHandler getUncaughtExceptionHandler() {
157 return uncaughtExceptionHandler;
158 }
159
160 public void setUncaughtExceptionHandler(UncaughtExceptionHandler handler) {
161 this.uncaughtExceptionHandler = handler;
162 }
163
164 }