1. Class definition
public class ThreadGroup implements Thread.UncaughtExceptionHandler
Copy the code
You can see this in the class definition
- ThreadGroup implements Thread. UncaughtExceptionHandler interface
The JDK is introduced
A thread group represents a set of threads. In addition, a thread group can also include other thread groups. The thread groups form a tree in which every thread group except the initial thread group has a parent.
A thread group represents a group of threads. In addition, thread groups can include other thread groups. Thread groups form a tree in which each thread group except the initial thread group has a parent
A thread is allowed to access information about its own thread group, but not to access information about its thread group’s parent thread group or any other thread groups.
Threads are allowed to access information about their own thread group, but not about their thread group’s parent thread group or any other thread group
2. Field attributes
// Parent thread group
private final ThreadGroup parent;
// The thread group name
String name;
// Maximum priority of a thread group
int maxPriority;
// Destroy state
boolean destroyed;
True: daemon thread group false: common thread group
boolean daemon;
boolean vmAllowSuspension;
// The number of threads not started, i.e. the number of threads in the NEW state
int nUnstartedThreads = 0;
// Size of the thread array
int nthreads;
// The thread of the current thread group
Thread threads[];
// The size of the child thread group
int ngroups;
// Child thread groups of the current thread group
ThreadGroup groups[];
Copy the code
You can see this in the field properties
- Threadgroups can have their own parent ThreadGroup
- Threadgroups can have their own child thread groups
- Threadgroups use an array of threads as storage containers
constructor
// Default constructor, private modifier, underlying call
private ThreadGroup(a) { // called from C code
// The default thread group name is system
this.name = "system";
// Maximum priority The default maximum priority of Thread is 10
this.maxPriority = Thread.MAX_PRIORITY;
// Parent thread group is null
this.parent = null;
}
// The name of the receiving thread group
public ThreadGroup(String name) {
// Call the following constructor
this(Thread.currentThread().getThreadGroup(), name);
}
// Receives a parent thread group and the thread group name
public ThreadGroup(ThreadGroup parent, String name) {
// Call the following constructor
// The first parameter needs to be noticed
this(checkParentAccess(parent), parent, name);
}
// Receives a Void argument with the parent thread group and the thread group name
// Void is a placeholder
private ThreadGroup(Void unused, ThreadGroup parent, String name) {
// Assign a value to the current thread group name
this.name = name;
// Maximum thread group priority is the maximum priority of the parent thread group
this.maxPriority = parent.maxPriority;
// Daemon state is the daemon state of the parent thread group
this.daemon = parent.daemon;
//vmAllowSuspension Sets the vmAllowSuspension of the parent thread group
this.vmAllowSuspension = parent.vmAllowSuspension;
// Set the incoming thread group to the parent thread group
this.parent = parent;
// The parent thread group adds the current thread to the child thread
parent.add(this);
}
Copy the code
You can see from the constructor
- The default thread group name is System, and the default constructor is private and is called by C code
- Parent thread group and thread group name can be specified during initialization
- The Void argument above is nice, say it again
Method 4.
CheckParentAccess method
// Check thread group access
private static Void checkParentAccess(ThreadGroup parent) {
parent.checkAccess();
return null;
}
Copy the code
GetName method
// Get the thread group name
public final String getName(a) {
return name;
}
Copy the code
GetParent method
// Get the parent thread group
public final ThreadGroup getParent(a) {
if(parent ! =null)
If the parent thread group is not null
// Check the parent thread group access
parent.checkAccess();
return parent;
}
Copy the code
GetMaxPriority method
// Get the maximum priority
public final int getMaxPriority(a) {
return maxPriority;
}
Copy the code
IsDaemon method
// Check if it is a daemon thread group
//true daemon thread group: If the last thread stops or the last thread group is destroyed, the current thread group is destroyed automatically
//false Common thread group: not destruct automatically
public final boolean isDaemon(a) {
return daemon;
}
Copy the code
IsDestroyed method
// Check whether the current thread group has been destroyed
public synchronized boolean isDestroyed(a) {
return destroyed;
}
Copy the code
SetDaemon method
// Sets whether the thread group is a daemon thread group
public final void setDaemon(boolean daemon) {
checkAccess();
this.daemon = daemon;
}
Copy the code
SetMaxPriority method
// Set the maximum priority
public final void setMaxPriority(int pri) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
//============== sync code block ===========
synchronized (this) {
// Check access permissions
checkAccess();
// Check parameters
if (pri < Thread.MIN_PRIORITY || pri > Thread.MAX_PRIORITY) {
return;
}
// If the parent thread group is not null, the maximum priority of pri and parent thread group is the lowest
// If the value is null, pri is used directlymaxPriority = (parent ! =null)? Math.min(pri, parent.maxPriority) : pri;// Copy the child thread group
ngroupsSnapshot = ngroups;
if(groups ! =null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null; }}//==============end===========
// Iterate to change the maximum priority of the child thread group
The maximum priority of the child thread group cannot be greater than the maximum priority of the parent thread group
for (int i = 0; i < ngroupsSnapshot ; i++) { groupsSnapshot[i].setMaxPriority(pri); }}Copy the code
ParentOf method
// Tests whether the passed thread group is the parent of the current thread group
public final boolean parentOf(ThreadGroup g) {
// do a recursive search
for(; g ! =null ; g = g.parent) {
if (g == this) {
// Find returns true
return true; }}// Return false if not found
return false;
}
Copy the code
Method checkAccess
// Check access permissions (whether there is permission to modify this thread)
public final void checkAccess(a) {
// Get the security manager
SecurityManager security = System.getSecurityManager();
if(security ! =null) {
// If the security manager is not null
// Invoke the security manager's access check method
security.checkAccess(this); }}Copy the code
ActiveCount method
// Returns the number of active threads in the current thread group and subthread group
// The value returned is an estimate, thread status is changing
public int activeCount(a) {
int result;
// Snapshot sub-group data so we don't hold this lock
// while our children are computing.
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
//============= sync code block =================
synchronized (this) {
if (destroyed) {
// If the thread group is destroyed, 0 is returned
return 0;
}
Nthreads Specifies the number of active threads in the current thread group
result = nthreads;
// Copy the child thread group
ngroupsSnapshot = ngroups;
if(groups ! =null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null; }}//=============end=================
// Loop recursively over the number of active threads in the child thread group
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
result += groupsSnapshot[i].activeCount();
}
// Returns the count of active threads
return result;
}
Copy the code
Enumerate method
// Copies the active threads of the Thread group and its subgroups into the specified Thread array
public int enumerate(Thread list[]) {
// Check access permissions
checkAccess();
// Call the following method
return enumerate(list, 0.true);
}
// Copies the active threads of the Thread group and its subgroups into the specified Thread array
private int enumerate(Thread list[], int n, boolean recurse) {
int ngroupsSnapshot = 0;
ThreadGroup[] groupsSnapshot = null;
//=========== sync code block ============
synchronized (this) {
if (destroyed) {
// If the current thread group is destroyed, 0 is returned
return 0;
}
int nt = nthreads;
// What does n stand for? Keep n lengths, right? The default is 0
if (nt > list.length - n) {
nt = list.length - n;
}
// Loop to add active threads for the current thread group
for (int i = 0; i < nt; i++) {
if(threads[i].isAlive()) { list[n++] = threads[i]; }}// If recurse is true, add the child thread group's active thread
if (recurse) {
ngroupsSnapshot = ngroups;
if(groups ! =null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null; }}}//===========end============
// If RECURse is true, recurse recursively adds the active thread of the child thread group
if (recurse) {
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
n = groupsSnapshot[i].enumerate(list, n, true); }}return n;
}
// Copies the active threads of the Thread group and its subgroups into the specified Thread array
// Resurse true Adds active thread to child group false Does not add child group thread
public int enumerate(Thread list[], boolean recurse) {
// Check access permissions
checkAccess();
// Call the above method
return enumerate(list, 0, recurse);
}
Copy the code
- The thread group approach is similar
ActiveGroupCount method
// Returns the number of active thread groups for the current thread group and its child thread group
public int activeGroupCount(a) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
if (destroyed) {
return 0;
}
ngroupsSnapshot = ngroups;
if(groups ! =null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null; }}// Assigns the number of current thread groups
int n = ngroupsSnapshot;
// Loop recursively through the number of thread groups of child thread groups
for (int i = 0 ; i < ngroupsSnapshot ; i++) {
n += groupsSnapshot[i].activeGroupCount();
}
return n;
}
Copy the code
Stop method
// Stops the threads of the thread group and all subthread groups
@Deprecated
public final void stop(a) {
// Stop the threads of the current thread group and all subthread groups
if (stopOrSuspend(false))
// Stop the current thread
Thread.currentThread().stop();
}
Copy the code
Suspend method
// Suspends the thread group and all child thread groups
@Deprecated
@SuppressWarnings("deprecation")
public final void suspend(a) {
// Suspends the thread and all child thread groups
if (stopOrSuspend(true))
// Suspend the current thread
Thread.currentThread().suspend();
}
Copy the code
StopOrSuspend method
// Stops or suspends all threads in the current thread group and child thread groups
@SuppressWarnings("deprecation")
private boolean stopOrSuspend(boolean suspend) {
boolean suicide = false;
// Get the current thread
Thread us = Thread.currentThread();
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot = null;
//=========== Synchronization method block =============
synchronized (this) {
// Check permissions
checkAccess();
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i]==us)
Suicide is set to true if the current traversal thread is the current calling thread
suicide = true;
else if (suspend)
//suspend true suspends the thread
threads[i].suspend();
else
//suspend False stops the thread
threads[i].stop();
}
ngroupsSnapshot = ngroups;
if(groups ! =null) { groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot); }}//===========end=============
// Loop recursively walks over threads that stop or suspend all child thread groups
for (int i = 0 ; i < ngroupsSnapshot ; i++)
suicide = groupsSnapshot[i].stopOrSuspend(suspend) || suicide;
return suicide;
}
Copy the code
Interrupt method
// Interrupts the thread group and all child thread groups
public final void interrupt(a) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
// Interrupts the thread of the current thread group
for (int i = 0 ; i < nthreads ; i++) {
threads[i].interrupt();
}
// Copy the child thread group
ngroupsSnapshot = ngroups;
if(groups ! =null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null; }}// Loop recursively interrupts the thread of the child thread group
for (int i = 0; i < ngroupsSnapshot ; i++) { groupsSnapshot[i].interrupt(); }}Copy the code
Resume method
// Restore the threads of the thread group and all subthread groups
@Deprecated
@SuppressWarnings("deprecation")
public final void resume(a) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
// Restore the thread of the current thread group
for (int i = 0 ; i < nthreads ; i++) {
threads[i].resume();
}
// Copy the child thread group
ngroupsSnapshot = ngroups;
if(groups ! =null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null; }}// Loop recursively to restore the thread of the child thread group
for (int i = 0; i < ngroupsSnapshot ; i++) { groupsSnapshot[i].resume(); }}Copy the code
Destroy methods
// Destroy the thread group and all child thread groups
public final void destroy(a) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
checkAccess();
if (destroyed || (nthreads > 0)) {
// Throw an exception if it has already been destroyed or there are still threads
throw new IllegalThreadStateException();
}
// Copy the child thread group
ngroupsSnapshot = ngroups;
if(groups ! =null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null;
}
if(parent ! =null) {
If the parent thread group is not null
// Clear all data
destroyed = true;
ngroups = 0;
groups = null;
nthreads = 0;
threads = null; }}// Loop recursively to destroy child thread groups
for (int i = 0 ; i < ngroupsSnapshot ; i += 1) {
groupsSnapshot[i].destroy();
}
if(parent ! =null) {
If the parent thread group is not null
// Remove yourself from the parent thread group
parent.remove(this); }}Copy the code
The add method
// Add a child thread group
private final void add(ThreadGroup g){
synchronized (this) {
if (destroyed) {
throw new IllegalThreadStateException();
}
if (groups == null) {
// If the subthread group array is null
// Creates an array of thread groups of size 4 by default
groups = new ThreadGroup[4];
} else if (ngroups == groups.length) {
// If the thread group array is full, double it
groups = Arrays.copyOf(groups, ngroups * 2);
}
/ / assignment
groups[ngroups] = g;
// Increase the number of thread groups by 1ngroups++; }}Copy the code
The remove method
// Remove a child thread group
private void remove(ThreadGroup g) {
synchronized (this) {
if (destroyed) {
// If the current thread group is destroyed, it is returned directly
return;
}
for (int i = 0 ; i < ngroups ; i++) {
// The for loop iterates through the search
if (groups[i] == g) {
// If found
// Reduce the number of child thread groups by 1
ngroups -= 1;
// Remove the current array of child threads
System.arraycopy(groups, i + 1, groups, i, ngroups - i);
// Set the last of the child thread array to NULL
groups[ngroups] = null;
// End the for loop
break; }}if (nthreads == 0) {
// If the current number of threads is 0
// Wake up all threads
notifyAll();
}
if (daemon && (nthreads == 0) &&
(nUnstartedThreads == 0) && (ngroups == 0))
{
// If it is a daemon thread group, and the number of threads and the array of child threads are 0
// Destroy the current thread groupdestroy(); }}}// Remove the thread
private void remove(Thread t) {
synchronized (this) {
if (destroyed) {
// If the thread group is destroyed, return directly
return;
}
// The for loop iterates through the search
for (int i = 0 ; i < nthreads ; i++) {
if (threads[i] == t) {
// If found
// Override to remove the current thread
System.arraycopy(threads, i + 1, threads, i, --nthreads - i);
// Set the last of the child thread array to NULL
threads[nthreads] = null;
// End the for loop
break; }}}}Copy the code
AddUnstarted method
// Add a thread in the NEW state
void addUnstarted(a) {
synchronized(this) {
if (destroyed) {
// If the current thread group is destroyed, an exception is thrown
throw new IllegalThreadStateException();
}
/ / nUnstartedThreads plus 1nUnstartedThreads++; }}Copy the code
The add method
// Add a thread
void add(Thread t) {
// Synchronize code blocks
synchronized (this) {
if (destroyed) {
// Throw an exception if destroyed
throw new IllegalThreadStateException();
}
if (threads == null) {
// If the current thread array is null
// Create an array of threads of size 4
threads = new Thread[4];
} else if (nthreads == threads.length) {
// If the current thread array is full
// Double the length
threads = Arrays.copyOf(threads, nthreads * 2);
}
// Add a thread
threads[nthreads] = t;
// The number of threads increases by 1
nthreads++;
// The number of threads not started is reduced by 1nUnstartedThreads--; }}Copy the code
ThreadStartFailed method
// Failed to start the thread
void threadStartFailed(Thread t) {
// Roll back the state and retry later
synchronized(this) {
// Remove the thread from the array
remove(t);
// Count of unstarted threads + 1nUnstartedThreads++; }}Copy the code
ThreadTerminated method
// The thread terminates
void threadTerminated(Thread t) {
synchronized (this) {
// Remove the thread from the array
remove(t);
if (nthreads == 0) {
// If the current active thread is 0
// Wake up all threads
notifyAll();
}
if (daemon && (nthreads == 0) &&
(nUnstartedThreads == 0) && (ngroups == 0))
{
// If it is a daemon thread group, and the number of threads and the array of child threads are 0
// Destroy the current thread groupdestroy(); }}}Copy the code
The list method
// Prints thread group information to standard output
public void list(a) {
// Call the following method
list(System.out, 0);
}
// Prints thread group information to standard output
void list(PrintStream out, int indent) {
int ngroupsSnapshot;
ThreadGroup[] groupsSnapshot;
synchronized (this) {
for (int j = 0 ; j < indent ; j++) {
out.print("");
}
out.println(this);
indent += 4;
// Prints information about the current thread
for (int i = 0 ; i < nthreads ; i++) {
for (int j = 0 ; j < indent ; j++) {
out.print("");
}
out.println(threads[i]);
}
// Copy the child thread group
ngroupsSnapshot = ngroups;
if(groups ! =null) {
groupsSnapshot = Arrays.copyOf(groups, ngroupsSnapshot);
} else {
groupsSnapshot = null; }}// Loop recursively to get the thread of the child thread
for (int i = 0; i < ngroupsSnapshot ; i++) { groupsSnapshot[i].list(out, indent); }}Copy the code
UncaughtException method
// The thread in the current thread group did not catch the exception callback, which is invoked by the virtual machine
public void uncaughtException(Thread t, Throwable e) {
if(parent ! =null) {
// Parent thread group is not null
// Go up
parent.uncaughtException(t, e);
} else {
// Displays abnormal information
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if(ueh ! =null) {
ueh.uncaughtException(t, e);
} else if(! (einstanceof ThreadDeath)) {
System.err.print("Exception in thread \""
+ t.getName() + "\" "); e.printStackTrace(System.err); }}}Copy the code
The toString method
// the toString method of ThreadGroup prints the class name and ThreadGroup name and maximum priority
public String toString(a) {
return getClass().getName() + "[name=" + getName() + ",maxpri=" + maxPriority + "]";
}
Copy the code