1
18 package net.bull.javamelody.internal.model;
19
20 import java.io.Serializable;
21 import java.lang.management.ManagementFactory;
22 import java.lang.management.ThreadMXBean;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.Collections;
26 import java.util.List;
27
28
36 public class ThreadInformations implements Serializable {
37 private static final long serialVersionUID = 3604281253550723654L;
38 @SuppressWarnings("all")
39 private static final ThreadMXBean THREAD_BEAN = ManagementFactory.getThreadMXBean();
40 private static final boolean CPU_TIME_ENABLED = THREAD_BEAN.isThreadCpuTimeSupported()
41 && THREAD_BEAN.isThreadCpuTimeEnabled();
42 private static final Method THREAD_ALLOCATED_BYTES_METHOD = getThreadAllocatedBytesMethod();
43 private final String name;
44 private final long id;
45 private final int priority;
46 private final boolean daemon;
47 private final Thread.State state;
48 private final long cpuTimeMillis;
49 private final long userTimeMillis;
50 private final boolean deadlocked;
51 private final String globalThreadId;
52 @SuppressWarnings("all")
53 private final List<StackTraceElement> stackTrace;
54
55 @SuppressWarnings("all")
56 public ThreadInformations(Thread thread, List<StackTraceElement> stackTrace, long cpuTimeMillis,
57 long userTimeMillis, boolean deadlocked, String hostAddress) {
58 super();
59 assert thread != null;
60 assert stackTrace == null || stackTrace instanceof Serializable;
61
62 this.name = thread.getName();
63 this.id = thread.getId();
64 this.priority = thread.getPriority();
65 this.daemon = thread.isDaemon();
66 this.state = thread.getState();
67 this.stackTrace = stackTrace;
68 this.cpuTimeMillis = cpuTimeMillis;
69 this.userTimeMillis = userTimeMillis;
70 this.deadlocked = deadlocked;
71 this.globalThreadId = buildGlobalThreadId(thread, hostAddress);
72 }
73
74 public static long getCurrentThreadCpuTime() {
75 return getThreadCpuTime(Thread.currentThread().getId());
76 }
77
78 static long getThreadCpuTime(long threadId) {
79 if (CPU_TIME_ENABLED) {
80
81 return THREAD_BEAN.getThreadCpuTime(threadId);
82 }
83 return 0;
84 }
85
86 public static long getCurrentThreadAllocatedBytes() {
87 return getThreadAllocatedBytes(Thread.currentThread().getId());
88 }
89
90 static long getThreadAllocatedBytes(long threadId) {
91
92
93 if (THREAD_ALLOCATED_BYTES_METHOD != null) {
94 try {
95 return (Long) THREAD_ALLOCATED_BYTES_METHOD.invoke(THREAD_BEAN, threadId);
96 } catch (final IllegalAccessException | InvocationTargetException e) {
97 throw new IllegalArgumentException(e);
98 }
99 }
100 return MBeansAccessor.getThreadAllocatedBytes(threadId);
101 }
102
103 private static Method getThreadAllocatedBytesMethod() {
104
105 try {
106 final Class<? extends ThreadMXBean> clazz = THREAD_BEAN.getClass();
107 final Method method = clazz.getMethod("getThreadAllocatedBytes", long.class);
108 if (method != null) {
109 method.setAccessible(true);
110
111 final Long bytes = (Long) method.invoke(THREAD_BEAN,
112 Thread.currentThread().getId());
113 if (bytes.longValue() != -1) {
114 return method;
115 }
116 }
117 return null;
118 } catch (final Exception e) {
119
120
121
122 return null;
123 }
124 }
125
126 public String getName() {
127 return name;
128 }
129
130 public long getId() {
131 return id;
132 }
133
134 public int getPriority() {
135 return priority;
136 }
137
138 public boolean isDaemon() {
139 return daemon;
140 }
141
142 public Thread.State getState() {
143 return state;
144 }
145
146 public List<StackTraceElement> getStackTrace() {
147 if (stackTrace != null) {
148 return Collections.unmodifiableList(stackTrace);
149 }
150 return stackTrace;
151 }
152
153 public String getExecutedMethod() {
154 final List<StackTraceElement> trace = stackTrace;
155 if (trace != null && !trace.isEmpty()) {
156 return trace.get(0).toString();
157 }
158 return "";
159 }
160
161 public long getCpuTimeMillis() {
162 return cpuTimeMillis;
163 }
164
165 public long getUserTimeMillis() {
166 return userTimeMillis;
167 }
168
169 public boolean isDeadlocked() {
170 return deadlocked;
171 }
172
173 public String getGlobalThreadId() {
174 return globalThreadId;
175 }
176
177 private static String buildGlobalThreadId(Thread thread, String hostAddress) {
178 return PID.getPID() + '_' + hostAddress + '_' + thread.getId();
179 }
180
181
182 @Override
183 public String toString() {
184 return getClass().getSimpleName() + "[id=" + getId() + ", name=" + getName() + ", daemon="
185 + isDaemon() + ", priority=" + getPriority() + ", deadlocked=" + isDeadlocked()
186 + ", state=" + getState() + ']';
187 }
188 }
189