aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spark-common/src/main/java/me/lucko/spark/sampler/ThreadDumper.java18
-rw-r--r--spark-common/src/main/java/me/lucko/spark/util/ThreadFinder.java (renamed from spark-common/src/main/java/me/lucko/spark/util/Threads.java)16
2 files changed, 24 insertions, 10 deletions
diff --git a/spark-common/src/main/java/me/lucko/spark/sampler/ThreadDumper.java b/spark-common/src/main/java/me/lucko/spark/sampler/ThreadDumper.java
index 61706f4..38cdd36 100644
--- a/spark-common/src/main/java/me/lucko/spark/sampler/ThreadDumper.java
+++ b/spark-common/src/main/java/me/lucko/spark/sampler/ThreadDumper.java
@@ -21,11 +21,13 @@
package me.lucko.spark.sampler;
-import me.lucko.spark.util.Threads;
+import me.lucko.spark.util.ThreadFinder;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;
@@ -56,6 +58,7 @@ public interface ThreadDumper {
* Implementation of {@link ThreadDumper} that generates data for a specific set of threads.
*/
final class Specific implements ThreadDumper {
+ private final ThreadFinder threadFinder = new ThreadFinder();
private final long[] ids;
public Specific(long[] ids) {
@@ -64,7 +67,7 @@ public interface ThreadDumper {
public Specific(Set<String> names) {
Set<String> namesLower = names.stream().map(String::toLowerCase).collect(Collectors.toSet());
- this.ids = Threads.getThreads()
+ this.ids = this.threadFinder.getThreads()
.filter(t -> namesLower.contains(t.getName().toLowerCase()))
.mapToLong(Thread::getId)
.toArray();
@@ -80,7 +83,9 @@ public interface ThreadDumper {
* Implementation of {@link ThreadDumper} that generates data for a regex matched set of threads.
*/
final class Regex implements ThreadDumper {
+ private final ThreadFinder threadFinder = new ThreadFinder();
private final Set<Pattern> namePatterns;
+ private final Map<Long, Boolean> cache = new HashMap<>();
public Regex(Set<String> namePatterns) {
this.namePatterns = namePatterns.stream()
@@ -97,13 +102,20 @@ public interface ThreadDumper {
@Override
public Iterable<ThreadInfo> dumpThreads(ThreadMXBean threadBean) {
- return Threads.getThreads()
+ return this.threadFinder.getThreads()
.filter(thread -> {
+ Boolean result = this.cache.get(thread.getId());
+ if (result != null) {
+ return result;
+ }
+
for (Pattern pattern : this.namePatterns) {
if (pattern.matcher(thread.getName()).matches()) {
+ this.cache.put(thread.getId(), true);
return true;
}
}
+ this.cache.put(thread.getId(), false);
return false;
})
.map(thread -> threadBean.getThreadInfo(thread.getId()))
diff --git a/spark-common/src/main/java/me/lucko/spark/util/Threads.java b/spark-common/src/main/java/me/lucko/spark/util/ThreadFinder.java
index d1efdff..a74f85a 100644
--- a/spark-common/src/main/java/me/lucko/spark/util/Threads.java
+++ b/spark-common/src/main/java/me/lucko/spark/util/ThreadFinder.java
@@ -25,14 +25,11 @@ import java.util.Objects;
import java.util.stream.Stream;
/**
- * Utilities for working with {@link Thread}s.
+ * Utility to find active threads.
*/
-public final class Threads {
-
- private Threads() {}
+public final class ThreadFinder {
private static final ThreadGroup ROOT_THREAD_GROUP;
-
static {
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
ThreadGroup parentGroup;
@@ -42,13 +39,18 @@ public final class Threads {
ROOT_THREAD_GROUP = rootGroup;
}
+ // cache the approx active count at the time of construction.
+ // the usages of this class are likely to be somewhat short-lived, so it's good
+ // enough to just cache a value on init.
+ private final int approxActiveCount = ROOT_THREAD_GROUP.activeCount();
+
/**
* Gets a stream of all known active threads.
*
* @return a stream of threads
*/
- public static Stream<Thread> getThreads() {
- Thread[] threads = new Thread[ROOT_THREAD_GROUP.activeCount()];
+ public Stream<Thread> getThreads() {
+ Thread[] threads = new Thread[this.approxActiveCount + 20]; // +20 to allow a bit of growth for newly created threads
while (ROOT_THREAD_GROUP.enumerate(threads, true ) == threads.length) {
threads = new Thread[threads.length * 2];
}