< prev index next > src/java.base/share/classes/jdk/internal/vm/ThreadContainers.java
Print this page
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
import java.util.stream.Stream;
import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets;
- import sun.nio.ch.Poller;
import sun.security.action.GetPropertyAction;
/**
- * This class consists exclusively of static methods to support debugging and
- * monitoring of threads.
+ * This class consists exclusively of static methods to support groupings of threads.
*/
public class ThreadContainers {
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
+ // true if all threads are tracked
+ private static final boolean TRACK_ALL_THREADS;
+
+ // the root container
+ private static final RootContainer ROOT_CONTAINER;
+
// the set of thread containers registered with this class
private static final Set<WeakReference<ThreadContainer>> CONTAINER_REGISTRY = ConcurrentHashMap.newKeySet();
private static final ReferenceQueue<Object> QUEUE = new ReferenceQueue<>();
+ static {
+ String s = GetPropertyAction.privilegedGetProperty("jdk.trackAllThreads");
+ if (s != null && (s.isEmpty() || Boolean.parseBoolean(s))) {
+ TRACK_ALL_THREADS = true;
+ ROOT_CONTAINER = new RootContainer.TrackingRootContainer();
+ } else {
+ TRACK_ALL_THREADS = false;
+ ROOT_CONTAINER = new RootContainer.CountingRootContainer();
+ }
+ }
+
private ThreadContainers() { }
/**
* Expunge stale entries from the container registry.
*/
while ((key = QUEUE.poll()) != null) {
CONTAINER_REGISTRY.remove(key);
}
}
+ /**
+ * Returns true if all threads are tracked.
+ */
+ public static boolean trackAllThreads() {
+ return TRACK_ALL_THREADS;
+ }
+
/**
* Registers a thread container to be tracked this class, returning a key
* that is used to remove it from the registry.
*/
public static Object registerContainer(ThreadContainer container) {
/**
* Returns the root thread container.
*/
public static ThreadContainer root() {
- return RootContainer.INSTANCE;
+ return ROOT_CONTAINER;
}
/**
* Returns the parent of the given thread container.
*
* Root container that "contains" all platform threads not started in a
* container plus some (or all) virtual threads that are started directly
* with the Thread API.
*/
private static abstract class RootContainer extends ThreadContainer {
- static final RootContainer INSTANCE;
- static {
- String s = GetPropertyAction.privilegedGetProperty("jdk.trackAllThreads");
- if (s != null && (s.isEmpty() || Boolean.parseBoolean(s))) {
- INSTANCE = new TrackingRootContainer();
- } else {
- INSTANCE = new CountingRootContainer();
- }
- }
protected RootContainer() {
super(true);
}
@Override
public ThreadContainer parent() {
return null;
}
@Override
- public String toString() {
+ public String name() {
return "<root>";
}
@Override
public StackableScope previous() {
return null;
}
+ @Override
+ public String toString() {
+ return name();
+ }
/**
* Returns the platform threads that are not in the container as these
* threads are considered to be in the root container.
*/
public long threadCount() {
return platformThreads().count() + VTHREAD_COUNT.sum();
}
@Override
public Stream<Thread> threads() {
- // virtual threads in this container that are those blocked on I/O.
- Stream<Thread> blockedVirtualThreads = Poller.blockedThreads()
- .filter(t -> t.isVirtual()
- && JLA.threadContainer(t) == this);
- return Stream.concat(platformThreads(), blockedVirtualThreads);
+ return platformThreads();
}
}
}
}
< prev index next >