diff options
author | Hen <hen@flamefew.com> | 2016-02-25 20:52:13 -0800 |
---|---|---|
committer | Hen <hen@flamefew.com> | 2016-02-25 20:52:13 -0800 |
commit | 69e97c8b42b9ad0880618132a613466f4e4779d3 (patch) | |
tree | 3586bd4a86aae42b345fa3573380074d9a99b3e3 /src/main/java/org/apache/commons/lang3/ThreadUtils.java | |
parent | a72a5ced53067d3516ffbebf00a633743bbfeb5c (diff) | |
download | apache-commons-lang-69e97c8b42b9ad0880618132a613466f4e4779d3.tar.gz |
Fixing crlfs
Diffstat (limited to 'src/main/java/org/apache/commons/lang3/ThreadUtils.java')
-rw-r--r-- | src/main/java/org/apache/commons/lang3/ThreadUtils.java | 920 |
1 files changed, 460 insertions, 460 deletions
diff --git a/src/main/java/org/apache/commons/lang3/ThreadUtils.java b/src/main/java/org/apache/commons/lang3/ThreadUtils.java index 15f0c5c05..89a59cea5 100644 --- a/src/main/java/org/apache/commons/lang3/ThreadUtils.java +++ b/src/main/java/org/apache/commons/lang3/ThreadUtils.java @@ -1,460 +1,460 @@ -/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.lang3;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * <p>
- * Helpers for {@code java.lang.Thread} and {@code java.lang.ThreadGroup}.
- * </p>
- * <p>
- * #ThreadSafe#
- * </p>
- *
- * @see java.lang.Thread
- * @see java.lang.ThreadGroup
- * @since 3.5
- */
-public class ThreadUtils {
-
- /**
- * Return the active thread with the specified id if it belong's to the specified thread group.
- *
- * @param threadId The thread id
- * @param threadGroup The thread group
- * @return The thread which belongs to a specified thread group and the thread's id match the specified id.
- * {@code null} is returned if no such thread exists
- * @throws IllegalArgumentException if the specified id is zero or negative or the group is null
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Thread findThreadById(final long threadId, final ThreadGroup threadGroup) {
- if (threadGroup == null) {
- throw new IllegalArgumentException("The thread group must not be null");
- }
- final Thread thread = findThreadById(threadId);
- if(thread != null && threadGroup.equals(thread.getThreadGroup())) {
- return thread;
- }
- return null;
- }
-
- /**
- * Return the active thread with the specified id if it belong's to a thread group with the specified group name.
- *
- * @param threadId The thread id
- * @param threadGroupName The thread group name
- * @return The threads which belongs to a thread group with the specified group name and the thread's id match the specified id.
- * {@code null} is returned if no such thread exists
- * @throws IllegalArgumentException if the specified id is zero or negative or the group name is null
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Thread findThreadById(final long threadId, final String threadGroupName) {
- if (threadGroupName == null) {
- throw new IllegalArgumentException("The thread group name must not be null");
- }
- final Thread thread = findThreadById(threadId);
- if(thread != null && thread.getThreadGroup() != null && thread.getThreadGroup().getName().equals(threadGroupName)) {
- return thread;
- }
- return null;
- }
-
- /**
- * Return active threads with the specified name if they belong to a specified thread group.
- *
- * @param threadName The thread name
- * @param threadGroup The thread group
- * @return The threads which belongs to a thread group and the thread's name match the specified name,
- * An empty collection is returned if no such thread exists. The collection returned is always unmodifiable.
- * @throws IllegalArgumentException if the specified thread name or group is null
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<Thread> findThreadsByName(final String threadName, final ThreadGroup threadGroup) {
- return findThreads(threadGroup, false, new NamePredicate(threadName));
- }
-
- /**
- * Return active threads with the specified name if they belong to a thread group with the specified group name.
- *
- * @param threadName The thread name
- * @param threadGroupName The thread group name
- * @return The threads which belongs to a thread group with the specified group name and the thread's name match the specified name,
- * An empty collection is returned if no such thread exists. The collection returned is always unmodifiable.
- * @throws IllegalArgumentException if the specified thread name or group name is null
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<Thread> findThreadsByName(final String threadName, final String threadGroupName) {
- if (threadName == null) {
- throw new IllegalArgumentException("The thread name must not be null");
- }
- if (threadGroupName == null) {
- throw new IllegalArgumentException("The thread group name must not be null");
- }
-
- final Collection<ThreadGroup> threadGroups = findThreadGroups(new NamePredicate(threadGroupName));
-
- if(threadGroups.isEmpty()) {
- return Collections.emptyList();
- }
-
- final Collection<Thread> result = new ArrayList<Thread>();
- final NamePredicate threadNamePredicate = new NamePredicate(threadName);
- for(final ThreadGroup group : threadGroups) {
- result.addAll(findThreads(group, false, threadNamePredicate));
- }
- return Collections.unmodifiableCollection(result);
- }
-
- /**
- * Return active thread groups with the specified group name.
- *
- * @param threadGroupName The thread group name
- * @return the thread groups with the specified group name or an empty collection if no such thread group exists. The collection returned is always unmodifiable.
- * @throws IllegalArgumentException if group name is null
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<ThreadGroup> findThreadGroupsByName(final String threadGroupName) {
- return findThreadGroups(new NamePredicate(threadGroupName));
- }
-
- /**
- * Return all active thread groups excluding the system thread group (A thread group is active if it has been not destroyed).
- *
- * @return all thread groups excluding the system thread group. The collection returned is always unmodifiable.
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<ThreadGroup> getAllThreadGroups() {
- return findThreadGroups(ALWAYS_TRUE_PREDICATE);
- }
-
- /**
- * Return the system thread group (sometimes also referred as "root thread group").
- *
- * @return the system thread group
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static ThreadGroup getSystemThreadGroup() {
- ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
- while(threadGroup.getParent() != null) {
- threadGroup = threadGroup.getParent();
- }
- return threadGroup;
- }
-
- /**
- * Return all active threads (A thread is active if it has been started and has not yet died).
- *
- * @return all active threads. The collection returned is always unmodifiable.
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<Thread> getAllThreads() {
- return findThreads(ALWAYS_TRUE_PREDICATE);
- }
-
- /**
- * Return active threads with the specified name.
- *
- * @param threadName The thread name
- * @return The threads with the specified name or an empty collection if no such thread exists. The collection returned is always unmodifiable.
- * @throws IllegalArgumentException if the specified name is null
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<Thread> findThreadsByName(final String threadName) {
- return findThreads(new NamePredicate(threadName));
- }
-
- /**
- * Return the active thread with the specified id.
- *
- * @param threadId The thread id
- * @return The thread with the specified id or {@code null} if no such thread exists
- * @throws IllegalArgumentException if the specified id is zero or negative
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- *
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Thread findThreadById(final long threadId) {
- final Collection<Thread> result = findThreads(new ThreadIdPredicate(threadId));
- return result.isEmpty() ? null : result.iterator().next();
- }
-
- /**
- * <p>
- * ThreadUtils instances should NOT be constructed in standard programming. Instead, the class should be used as
- * {@code ThreadUtils.getAllThreads()}
- * </p>
- * <p>
- * This constructor is public to permit tools that require a JavaBean instance to operate.
- * </p>
- */
- public ThreadUtils() {
- super();
- }
-
- /**
- * A predicate for selecting threads.
- */
- //if java minimal version for lang becomes 1.8 extend this interface from java.util.function.Predicate
- public interface ThreadPredicate /*extends java.util.function.Predicate<Thread>*/{
-
- /**
- * Evaluates this predicate on the given thread.
- * @param thread the thread
- * @return {@code true} if the thread matches the predicate, otherwise {@code false}
- */
- boolean test(Thread thread);
- }
-
- /**
- * A predicate for selecting threadgroups.
- */
- //if java minimal version for lang becomes 1.8 extend this interface from java.util.function.Predicate
- public interface ThreadGroupPredicate /*extends java.util.function.Predicate<ThreadGroup>*/{
-
- /**
- * Evaluates this predicate on the given threadgroup.
- * @param threadGroup the threadgroup
- * @return {@code true} if the threadGroup matches the predicate, otherwise {@code false}
- */
- boolean test(ThreadGroup threadGroup);
- }
-
- /**
- * Predicate which always returns true.
- */
- public static final AlwaysTruePredicate ALWAYS_TRUE_PREDICATE = new AlwaysTruePredicate();
-
- /**
- * A predicate implementation which always returns true.
- */
- private final static class AlwaysTruePredicate implements ThreadPredicate, ThreadGroupPredicate{
-
- private AlwaysTruePredicate() {
- }
-
- @Override
- public boolean test(final ThreadGroup threadGroup) {
- return true;
- }
-
- @Override
- public boolean test(final Thread thread) {
- return true;
- }
- }
-
- /**
- * A predicate implementation which matches a thread or threadgroup name.
- */
- public static class NamePredicate implements ThreadPredicate, ThreadGroupPredicate {
-
- private final String name;
-
- /**
- * Predicate constructor
- *
- * @param name thread or threadgroup name
- * @throws IllegalArgumentException if the name is {@code null}
- */
- public NamePredicate(final String name) {
- super();
- if (name == null) {
- throw new IllegalArgumentException("The name must not be null");
- }
- this.name = name;
- }
-
- @Override
- public boolean test(final ThreadGroup threadGroup) {
- return threadGroup != null && threadGroup.getName().equals(name);
- }
-
- @Override
- public boolean test(final Thread thread) {
- return thread != null && thread.getName().equals(name);
- }
- }
-
- /**
- * A predicate implementation which matches a thread id.
- */
- public static class ThreadIdPredicate implements ThreadPredicate {
-
- private final long threadId;
-
- /**
- * Predicate constructor
- *
- * @param threadId the threadId to match
- * @throws IllegalArgumentException if the threadId is zero or negative
- */
- public ThreadIdPredicate(final long threadId) {
- super();
- if (threadId <= 0) {
- throw new IllegalArgumentException("The thread id must be greater than zero");
- }
- this.threadId = threadId;
- }
-
- @Override
- public boolean test(final Thread thread) {
- return thread != null && thread.getId() == threadId;
- }
- }
-
- /**
- * Select all active threads which match the given predicate.
- *
- * @param predicate the predicate
- * @return An unmodifiable {@code Collection} of active threads matching the given predicate
- *
- * @throws IllegalArgumentException if the predicate is null
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<Thread> findThreads(final ThreadPredicate predicate){
- return findThreads(getSystemThreadGroup(), true, predicate);
- }
-
- /**
- * Select all active threadgroups which match the given predicate.
- *
- * @param predicate the predicate
- * @return An unmodifiable {@code Collection} of active threadgroups matching the given predicate
- * @throws IllegalArgumentException if the predicate is null
- * @throws SecurityException
- * if the current thread cannot access the system thread group
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<ThreadGroup> findThreadGroups(final ThreadGroupPredicate predicate){
- return findThreadGroups(getSystemThreadGroup(), true, predicate);
- }
-
- /**
- * Select all active threads which match the given predicate and which belongs to the given thread group (or one of its subgroups).
- *
- * @param group the thread group
- * @param recurse if {@code true} then evaluate the predicate recursively on all threads in all subgroups of the given group
- * @param predicate the predicate
- * @return An unmodifiable {@code Collection} of active threads which match the given predicate and which belongs to the given thread group
- * @throws IllegalArgumentException if the given group or predicate is null
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<Thread> findThreads(final ThreadGroup group, final boolean recurse, final ThreadPredicate predicate) {
- if (group == null) {
- throw new IllegalArgumentException("The group must not be null");
- }
- if (predicate == null) {
- throw new IllegalArgumentException("The predicate must not be null");
- }
-
- int count = group.activeCount();
- Thread[] threads;
- do {
- threads = new Thread[count + (count / 2) + 1]; //slightly grow the array size
- count = group.enumerate(threads, recurse);
- //return value of enumerate() must be strictly less than the array size according to javadoc
- } while (count >= threads.length);
-
- final List<Thread> result = new ArrayList<Thread>(count);
- for (int i = 0; i < count; ++i) {
- if (predicate.test(threads[i])) {
- result.add(threads[i]);
- }
- }
- return Collections.unmodifiableCollection(result);
- }
-
- /**
- * Select all active threadgroups which match the given predicate and which is a subgroup of the given thread group (or one of its subgroups).
- *
- * @param group the thread group
- * @param recurse if {@code true} then evaluate the predicate recursively on all threadgroups in all subgroups of the given group
- * @param predicate the predicate
- * @return An unmodifiable {@code Collection} of active threadgroups which match the given predicate and which is a subgroup of the given thread group
- * @throws IllegalArgumentException if the given group or predicate is null
- * @throws SecurityException if the current thread cannot modify
- * thread groups from this thread's thread group up to the system thread group
- */
- public static Collection<ThreadGroup> findThreadGroups(final ThreadGroup group, final boolean recurse, final ThreadGroupPredicate predicate){
- if (group == null) {
- throw new IllegalArgumentException("The group must not be null");
- }
- if (predicate == null) {
- throw new IllegalArgumentException("The predicate must not be null");
- }
-
- int count = group.activeGroupCount();
- ThreadGroup[] threadGroups;
- do {
- threadGroups = new ThreadGroup[count + (count / 2) + 1]; //slightly grow the array size
- count = group.enumerate(threadGroups, recurse);
- //return value of enumerate() must be strictly less than the array size according to javadoc
- } while(count >= threadGroups.length);
-
- final List<ThreadGroup> result = new ArrayList<ThreadGroup>(count);
- for(int i = 0; i < count; ++i) {
- if(predicate.test(threadGroups[i])) {
- result.add(threadGroups[i]);
- }
- }
- return Collections.unmodifiableCollection(result);
- }
-}
+/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.lang3; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * <p> + * Helpers for {@code java.lang.Thread} and {@code java.lang.ThreadGroup}. + * </p> + * <p> + * #ThreadSafe# + * </p> + * + * @see java.lang.Thread + * @see java.lang.ThreadGroup + * @since 3.5 + */ +public class ThreadUtils { + + /** + * Return the active thread with the specified id if it belong's to the specified thread group. + * + * @param threadId The thread id + * @param threadGroup The thread group + * @return The thread which belongs to a specified thread group and the thread's id match the specified id. + * {@code null} is returned if no such thread exists + * @throws IllegalArgumentException if the specified id is zero or negative or the group is null + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Thread findThreadById(final long threadId, final ThreadGroup threadGroup) { + if (threadGroup == null) { + throw new IllegalArgumentException("The thread group must not be null"); + } + final Thread thread = findThreadById(threadId); + if(thread != null && threadGroup.equals(thread.getThreadGroup())) { + return thread; + } + return null; + } + + /** + * Return the active thread with the specified id if it belong's to a thread group with the specified group name. + * + * @param threadId The thread id + * @param threadGroupName The thread group name + * @return The threads which belongs to a thread group with the specified group name and the thread's id match the specified id. + * {@code null} is returned if no such thread exists + * @throws IllegalArgumentException if the specified id is zero or negative or the group name is null + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Thread findThreadById(final long threadId, final String threadGroupName) { + if (threadGroupName == null) { + throw new IllegalArgumentException("The thread group name must not be null"); + } + final Thread thread = findThreadById(threadId); + if(thread != null && thread.getThreadGroup() != null && thread.getThreadGroup().getName().equals(threadGroupName)) { + return thread; + } + return null; + } + + /** + * Return active threads with the specified name if they belong to a specified thread group. + * + * @param threadName The thread name + * @param threadGroup The thread group + * @return The threads which belongs to a thread group and the thread's name match the specified name, + * An empty collection is returned if no such thread exists. The collection returned is always unmodifiable. + * @throws IllegalArgumentException if the specified thread name or group is null + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<Thread> findThreadsByName(final String threadName, final ThreadGroup threadGroup) { + return findThreads(threadGroup, false, new NamePredicate(threadName)); + } + + /** + * Return active threads with the specified name if they belong to a thread group with the specified group name. + * + * @param threadName The thread name + * @param threadGroupName The thread group name + * @return The threads which belongs to a thread group with the specified group name and the thread's name match the specified name, + * An empty collection is returned if no such thread exists. The collection returned is always unmodifiable. + * @throws IllegalArgumentException if the specified thread name or group name is null + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<Thread> findThreadsByName(final String threadName, final String threadGroupName) { + if (threadName == null) { + throw new IllegalArgumentException("The thread name must not be null"); + } + if (threadGroupName == null) { + throw new IllegalArgumentException("The thread group name must not be null"); + } + + final Collection<ThreadGroup> threadGroups = findThreadGroups(new NamePredicate(threadGroupName)); + + if(threadGroups.isEmpty()) { + return Collections.emptyList(); + } + + final Collection<Thread> result = new ArrayList<Thread>(); + final NamePredicate threadNamePredicate = new NamePredicate(threadName); + for(final ThreadGroup group : threadGroups) { + result.addAll(findThreads(group, false, threadNamePredicate)); + } + return Collections.unmodifiableCollection(result); + } + + /** + * Return active thread groups with the specified group name. + * + * @param threadGroupName The thread group name + * @return the thread groups with the specified group name or an empty collection if no such thread group exists. The collection returned is always unmodifiable. + * @throws IllegalArgumentException if group name is null + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<ThreadGroup> findThreadGroupsByName(final String threadGroupName) { + return findThreadGroups(new NamePredicate(threadGroupName)); + } + + /** + * Return all active thread groups excluding the system thread group (A thread group is active if it has been not destroyed). + * + * @return all thread groups excluding the system thread group. The collection returned is always unmodifiable. + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<ThreadGroup> getAllThreadGroups() { + return findThreadGroups(ALWAYS_TRUE_PREDICATE); + } + + /** + * Return the system thread group (sometimes also referred as "root thread group"). + * + * @return the system thread group + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static ThreadGroup getSystemThreadGroup() { + ThreadGroup threadGroup = Thread.currentThread().getThreadGroup(); + while(threadGroup.getParent() != null) { + threadGroup = threadGroup.getParent(); + } + return threadGroup; + } + + /** + * Return all active threads (A thread is active if it has been started and has not yet died). + * + * @return all active threads. The collection returned is always unmodifiable. + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<Thread> getAllThreads() { + return findThreads(ALWAYS_TRUE_PREDICATE); + } + + /** + * Return active threads with the specified name. + * + * @param threadName The thread name + * @return The threads with the specified name or an empty collection if no such thread exists. The collection returned is always unmodifiable. + * @throws IllegalArgumentException if the specified name is null + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<Thread> findThreadsByName(final String threadName) { + return findThreads(new NamePredicate(threadName)); + } + + /** + * Return the active thread with the specified id. + * + * @param threadId The thread id + * @return The thread with the specified id or {@code null} if no such thread exists + * @throws IllegalArgumentException if the specified id is zero or negative + * @throws SecurityException + * if the current thread cannot access the system thread group + * + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Thread findThreadById(final long threadId) { + final Collection<Thread> result = findThreads(new ThreadIdPredicate(threadId)); + return result.isEmpty() ? null : result.iterator().next(); + } + + /** + * <p> + * ThreadUtils instances should NOT be constructed in standard programming. Instead, the class should be used as + * {@code ThreadUtils.getAllThreads()} + * </p> + * <p> + * This constructor is public to permit tools that require a JavaBean instance to operate. + * </p> + */ + public ThreadUtils() { + super(); + } + + /** + * A predicate for selecting threads. + */ + //if java minimal version for lang becomes 1.8 extend this interface from java.util.function.Predicate + public interface ThreadPredicate /*extends java.util.function.Predicate<Thread>*/{ + + /** + * Evaluates this predicate on the given thread. + * @param thread the thread + * @return {@code true} if the thread matches the predicate, otherwise {@code false} + */ + boolean test(Thread thread); + } + + /** + * A predicate for selecting threadgroups. + */ + //if java minimal version for lang becomes 1.8 extend this interface from java.util.function.Predicate + public interface ThreadGroupPredicate /*extends java.util.function.Predicate<ThreadGroup>*/{ + + /** + * Evaluates this predicate on the given threadgroup. + * @param threadGroup the threadgroup + * @return {@code true} if the threadGroup matches the predicate, otherwise {@code false} + */ + boolean test(ThreadGroup threadGroup); + } + + /** + * Predicate which always returns true. + */ + public static final AlwaysTruePredicate ALWAYS_TRUE_PREDICATE = new AlwaysTruePredicate(); + + /** + * A predicate implementation which always returns true. + */ + private final static class AlwaysTruePredicate implements ThreadPredicate, ThreadGroupPredicate{ + + private AlwaysTruePredicate() { + } + + @Override + public boolean test(final ThreadGroup threadGroup) { + return true; + } + + @Override + public boolean test(final Thread thread) { + return true; + } + } + + /** + * A predicate implementation which matches a thread or threadgroup name. + */ + public static class NamePredicate implements ThreadPredicate, ThreadGroupPredicate { + + private final String name; + + /** + * Predicate constructor + * + * @param name thread or threadgroup name + * @throws IllegalArgumentException if the name is {@code null} + */ + public NamePredicate(final String name) { + super(); + if (name == null) { + throw new IllegalArgumentException("The name must not be null"); + } + this.name = name; + } + + @Override + public boolean test(final ThreadGroup threadGroup) { + return threadGroup != null && threadGroup.getName().equals(name); + } + + @Override + public boolean test(final Thread thread) { + return thread != null && thread.getName().equals(name); + } + } + + /** + * A predicate implementation which matches a thread id. + */ + public static class ThreadIdPredicate implements ThreadPredicate { + + private final long threadId; + + /** + * Predicate constructor + * + * @param threadId the threadId to match + * @throws IllegalArgumentException if the threadId is zero or negative + */ + public ThreadIdPredicate(final long threadId) { + super(); + if (threadId <= 0) { + throw new IllegalArgumentException("The thread id must be greater than zero"); + } + this.threadId = threadId; + } + + @Override + public boolean test(final Thread thread) { + return thread != null && thread.getId() == threadId; + } + } + + /** + * Select all active threads which match the given predicate. + * + * @param predicate the predicate + * @return An unmodifiable {@code Collection} of active threads matching the given predicate + * + * @throws IllegalArgumentException if the predicate is null + * @throws SecurityException + * if the current thread cannot access the system thread group + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<Thread> findThreads(final ThreadPredicate predicate){ + return findThreads(getSystemThreadGroup(), true, predicate); + } + + /** + * Select all active threadgroups which match the given predicate. + * + * @param predicate the predicate + * @return An unmodifiable {@code Collection} of active threadgroups matching the given predicate + * @throws IllegalArgumentException if the predicate is null + * @throws SecurityException + * if the current thread cannot access the system thread group + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<ThreadGroup> findThreadGroups(final ThreadGroupPredicate predicate){ + return findThreadGroups(getSystemThreadGroup(), true, predicate); + } + + /** + * Select all active threads which match the given predicate and which belongs to the given thread group (or one of its subgroups). + * + * @param group the thread group + * @param recurse if {@code true} then evaluate the predicate recursively on all threads in all subgroups of the given group + * @param predicate the predicate + * @return An unmodifiable {@code Collection} of active threads which match the given predicate and which belongs to the given thread group + * @throws IllegalArgumentException if the given group or predicate is null + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<Thread> findThreads(final ThreadGroup group, final boolean recurse, final ThreadPredicate predicate) { + if (group == null) { + throw new IllegalArgumentException("The group must not be null"); + } + if (predicate == null) { + throw new IllegalArgumentException("The predicate must not be null"); + } + + int count = group.activeCount(); + Thread[] threads; + do { + threads = new Thread[count + (count / 2) + 1]; //slightly grow the array size + count = group.enumerate(threads, recurse); + //return value of enumerate() must be strictly less than the array size according to javadoc + } while (count >= threads.length); + + final List<Thread> result = new ArrayList<Thread>(count); + for (int i = 0; i < count; ++i) { + if (predicate.test(threads[i])) { + result.add(threads[i]); + } + } + return Collections.unmodifiableCollection(result); + } + + /** + * Select all active threadgroups which match the given predicate and which is a subgroup of the given thread group (or one of its subgroups). + * + * @param group the thread group + * @param recurse if {@code true} then evaluate the predicate recursively on all threadgroups in all subgroups of the given group + * @param predicate the predicate + * @return An unmodifiable {@code Collection} of active threadgroups which match the given predicate and which is a subgroup of the given thread group + * @throws IllegalArgumentException if the given group or predicate is null + * @throws SecurityException if the current thread cannot modify + * thread groups from this thread's thread group up to the system thread group + */ + public static Collection<ThreadGroup> findThreadGroups(final ThreadGroup group, final boolean recurse, final ThreadGroupPredicate predicate){ + if (group == null) { + throw new IllegalArgumentException("The group must not be null"); + } + if (predicate == null) { + throw new IllegalArgumentException("The predicate must not be null"); + } + + int count = group.activeGroupCount(); + ThreadGroup[] threadGroups; + do { + threadGroups = new ThreadGroup[count + (count / 2) + 1]; //slightly grow the array size + count = group.enumerate(threadGroups, recurse); + //return value of enumerate() must be strictly less than the array size according to javadoc + } while(count >= threadGroups.length); + + final List<ThreadGroup> result = new ArrayList<ThreadGroup>(count); + for(int i = 0; i < count; ++i) { + if(predicate.test(threadGroups[i])) { + result.add(threadGroups[i]); + } + } + return Collections.unmodifiableCollection(result); + } +} |