-
Notifications
You must be signed in to change notification settings - Fork 338
Expand file tree
/
Copy pathThreadUtils.java
More file actions
85 lines (74 loc) · 2.68 KB
/
ThreadUtils.java
File metadata and controls
85 lines (74 loc) · 2.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package datadog.environment;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
/**
* Helper class for working with Threads
*
* <p>Uses feature detection and provides static helpers to work with different versions of Java
*
* <p>This class is designed to use MethodHandles that constant propagate to minimize the overhead
*/
public final class ThreadUtils {
static final MethodHandle H_IS_VIRTUAL = lookupIsVirtual();
static final MethodHandle H_ID = lookupId();
private ThreadUtils() {}
/** Provides the best id available for the Thread Uses threadId on 19+; getId on older JVMs */
public static final long threadId(Thread thread) {
try {
return (long) H_ID.invoke(thread);
} catch (Throwable t) {
return 0L;
}
}
/** Indicates whether virtual threads are supported on this JVM */
public static final boolean supportsVirtualThreads() {
return (H_IS_VIRTUAL != null);
}
/** Indicates if the current thread is a virtual thread */
public static final boolean isCurrentThreadVirtual() {
// H_IS_VIRTUAL will constant propagate -- then dead code eliminate -- and inline as needed
try {
return (H_IS_VIRTUAL != null) && (boolean) H_IS_VIRTUAL.invoke(Thread.currentThread());
} catch (Throwable t) {
return false;
}
}
/** Indicates if the provided thread is a virtual thread */
public static final boolean isVirtual(Thread thread) {
// H_IS_VIRTUAL will constant propagate -- then dead code eliminate -- and inline as needed
try {
return (H_IS_VIRTUAL != null) && (boolean) H_IS_VIRTUAL.invoke(thread);
} catch (Throwable t) {
return false;
}
}
private static final MethodHandle lookupIsVirtual() {
try {
return MethodHandles.lookup()
.findVirtual(Thread.class, "isVirtual", MethodType.methodType(boolean.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
return null;
}
}
private static final MethodHandle lookupId() {
MethodHandle threadIdHandle = lookupThreadId();
return threadIdHandle != null ? threadIdHandle : lookupGetId();
}
private static final MethodHandle lookupThreadId() {
try {
return MethodHandles.lookup()
.findVirtual(Thread.class, "threadId", MethodType.methodType(long.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
return null;
}
}
private static final MethodHandle lookupGetId() {
try {
return MethodHandles.lookup()
.findVirtual(Thread.class, "getId", MethodType.methodType(long.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
return null;
}
}
}