All threads are subordinate to a single thread group. That can be a default thread group, or a group that is explicitly specified when a thread is created. At the beginning of creation, threads are restricted to a group and cannot be changed to a different group. Each application has at least one thread that is subordinate to the system thread group. If you create multiple threads without specifying a group, they are automatically attributed to the system thread group. The
Thread group must also be subordinate to other thread groups. You must specify in the builder which thread group the new thread group belongs to. If you create a thread group without specifying its attribution, you will also automatically become a subordinate of the system thread group. As a result, all the thread groups in an application will eventually take the system thread group as their "parent." The idea of a "thread group" is difficult for the
to find out literally. This has brought some confusion to the subject of our discussion. Generally speaking, we think that the thread group is used for "security" or "confidentiality" reasons. According to Arnold and Gosling: "Threads in a thread group can modify other threads within a group, including those that reside in the deepest layers of the hierarchy." A thread cannot modify any thread that is outside its own group or subordinate group (note ①). However, it is difficult to tell what the specific meaning of "modification" is here. The following example shows a thread in a "leaf group" that modifies the priority of all threads in its thread group tree, and also calls a method for all threads in the tree.
①: Page 179th of the Java programming Language. The book was edited by Arnold and Jams Gosling, and Addison-wesley published
in 1996;
: Testaccess.java//How threads can access other threads//in a parent thread group public class Testaccess {Publ
IC static void Main (string[] args) {Threadgroup x = new Threadgroup ("X"), y = new Threadgroup (x, "Y"),
z = new Threadgroup (y, "z");
Thread one = new TestThread1 (x, "one"), two = new TestThread2 (Z, "two");
} class TestThread1 extends Thread {private int i;
TestThread1 (Threadgroup G, String name) {Super (G, name);
} void F () {i++;//Modify this thread System.out.println (getName () + "f ()");
} class TestThread2 extends TestThread1 {TestThread2 (threadgroup g, String name) {Super (G, name);
Start ();
public void Run () {Threadgroup g = Getthreadgroup (). GetParent (). GetParent ();
G.list ();
thread[] GAll = new Thread[g.activecount ()];
G.enumerate (GALL);
for (int i = 0; i < gall.length i++) {gall[i].setpriority (thread.min_priority); ((TESTTHREAD1)Gall[i]). f ();
} g.list (); }
} ///:~
in Main (), we create several threadgroup (thread groups), each on a different "leaf": X has no parameters, only its name (a string), so it automatically enters the system thread group, and y is below X, and z is below Y. Note that initialization is done in text order, so the code is legal. The
has two threads created and entered a different thread group. Among them, TestThread1 does not have a run () method, but there is an F () that notifies the thread and prints something so that we know it has been invoked. and TestThread2 belongs to a subclass of TestThread1, it's run () very detailed, to do a lot of things. First, it gets the thread group where the current thread is located, and then uses GetParent () to move up level two in the inheritance tree (this makes sense because I want to move the TestThread2 down two levels in the hierarchy). Then we call Method Activecount (), querying the thread group and how many threads are in all child thread groups, creating an array of handles that point to thread. The enumerate () method will point to the handle of all these threads in the array gall. The entire array is then traversed, and the F () method is called for each thread, while the priority is modified. As a result, the thread in a "leaf" thread group modifies the thread that is in the parent thread group. The
Debug Method list () prints out all the information related to a thread group as standard output. When we investigate the behavior of thread groups, it is quite beneficial to do so. The following is the output of the program:
JAVA.LANG.THREADGROUP[NAME=X,MAXPRI=10]
thread[one,5,x]
java.lang.threadgroup[name=y,maxpri=10]
JAVA.LANG.THREADGROUP[NAME=Z,MAXPRI=10]
Thread[two,5,z] one
f ()
two F ()
java.lang.threadgroup[ NAME=X,MAXPRI=10]
thread[one,1,x]
java.lang.threadgroup[name=y,maxpri=10]
java.lang.threadgroup[ NAME=Z,MAXPRI=10]
Thread[two,1,z]
The list () prints out not only the class name of Threadgroup or thread, but also the name of the thread group and its highest priority. For threads, print out their names and connect to the line priority and the thread group to which they belong. Note that the list () indents threads and thread groups, indicating that they are "children" of the not-indented thread group.
You can see that f () is called by the TestThread2 Run () method, so it's obvious that all the threads in the group are pretty fragile. However, we can only access those threads that are branching out from our own system thread group tree, and perhaps that's what "security" means. We cannot access anyone else's system thread tree.
1. Control of Thread Group
Aside from security issues, one of the most useful parts of a thread group is control: it takes only a single command to complete the operation of the entire thread group. The following example illustrates this and gives a description of the precedence limits within the thread group. The number of comments in parentheses allows you to compare the output:
: Threadgroup1.java//How to thread groups control priorities//of the threads inside them.
public class ThreadGroup1 {public static void main (string[] args) {//Get "system thread & print its Info:
Threadgroup sys = Thread.CurrentThread (). Getthreadgroup (); Sys.list ();
(1)//Reduce The system thread Group priority:sys.setMaxPriority (thread.max_priority-1);
Increase the main thread priority:thread Curr = Thread.CurrentThread ();
Curr.setpriority (curr.getpriority () + 1); Sys.list ();
(2)//attempt to set a new group to the max:threadgroup g1 = new Threadgroup ("G1");
G1.setmaxpriority (thread.max_priority);
Attempt to set a new thread to the max:thread t = new Thread (G1, "a");
T.setpriority (thread.max_priority); G1.list (); (3)//Reduce G1 ' max priority, then attempt/to increase it:g1.setMaxPriority (thread.max_priority-2)
;
G1.setmaxpriority (thread.max_priority); G1.list ();
(4)//attempt to set a new thread to the MAX:T = new Thread (G1, "B");
T.setpriority (thread.max_priority); G1.list (); (5)//Lower The max priority below the default//thread priority:g1.setMaxPriority (thread.min_priority +
2);
Look in a new thread ' s priority before//and after changing it:t = new Thread (G1, "C"); G1.list ();
(6) T.setpriority (T.getpriority ()-1); G1.list (); (7)//Make G2 a child threadgroup of G1 and//try to increase its priority:threadgroup g2 = new THREADGR
OUP (G1, "G2"); G2.list ();
(8) g2.setmaxpriority (thread.max_priority); G2.list (); (9)//ADD a bunch of new threads to g2:for (int i = 0; i < 5; i++) New Thread (G2, integer.tostring (i
)); Show information about all threadgroups//and Threads:sys.list ();
(a) System.out.println ("Starting All Threads:");
thread[] All = new Thread[sys.activecount ()]; SYs.enumerate (All);
for (int i = 0; i < all.length i++) if (!all[i].isalive ()) All[i].start (); Suspends & Stops All threads in//this group and its subgroups:System.out.println ("All Threads Started")
; Sys.suspend ();
Deprecated in Java 1.2//Never gets ...
System.out.println ("All Threads suspended"); Sys.stop ();
Deprecated in Java 1.2 System.out.println ("All Threads Stopped"); }
} ///:~
The output below
is appropriately edited so that one page can be mounted (java.lang. has been deleted), and the appropriate number is added, corresponding to the number in parentheses in the previous list of programs:
(1) threadgroup[name=system,maxpri=10] Thread[main,5,system] (2) Threadgroup[name=system,maxpri
=9] Thread[main,6,system] (3) threadgroup[name=g1,maxpri=9] THREAD[A,9,G1] (4) threadgroup[name=g1,maxpri=8] THREAD[A,9,G1] (5) threadgroup[name=g1,maxpri=8] thread[a,9,g1] thread[b,8,g1] (6) Threadgroup[name=g1,ma Xpri=3] thread[a,9,g1] thread[b,8,g1] thread[c,6,g1] (7) threadgroup[name=g1,maxpri=3] thread[a,9, G1] THREAD[B,8,G1] THREAD[C,3,G1] (8) threadgroup[name=g2,maxpri=3] (9) threadgroup[name=g2,maxpri=3] (a) Thre
ADGROUP[NAME=SYSTEM,MAXPRI=9] Thread[main,6,system] threadgroup[name=g1,maxpri=3] THREAD[A,9,G1] THREAD[B,8,G1] thread[c,3,g1] threadgroup[name=g2,maxpri=3] thread[0,6,g2] thread[1 , 6,g2] thread[2,6,g2] thread[3,6,g2] thread[4,6,g2] starting all Threads:all threads D
All programs have at least one thread running, and the first action that main () takes is to invoke a static (static) method of thread, named CurrentThread (). Starting with this thread, the thread group is created and the list () is called for the result. The output is as follows:
(1) threadgroup[name=system,maxpri=10]
Thread[main,5,system]
As we can see, the main thread group's name is System, and the main thread's name is main, and it belongs to the system thread group.
The second exercise shows that the highest priority of the system group can be reduced, and the main thread can increase its priority:
(2) threadgroup[name=system,maxpri=9]
Thread[main,6,system]
The third exercise creates a new thread group, named G1, which automatically belongs to the system thread group because it does not explicitly specify its attribution relationship. We placed a new thread inside the G1, named A. We then try to set the maximum priority for this group to the highest level and set A's priority to the highest level. The results are as follows:
(3) threadgroup[name=g1,maxpri=9]
THREAD[A,9,G1]
As you can see, it is not possible to set the maximum priority of a thread group above its parent thread group.
The fourth exercise will reduce the maximum priority of G1 by two, and then try to lift it to thread.max_priority. The results are as follows:
(4) threadgroup[name=g1,maxpri=8]
THREAD[A,9,G1]
It can also be seen that the attempt to increase the maximum priority is a failure. We can only reduce the maximum priority of one thread group and not improve it. Also, note that the priority of thread A does not change, and that it is now higher than the maximum priority of the thread group. That is, the change in the maximum priority of the thread group does not affect existing threads.
The fifth exercise tries to Cheng a new line as the maximum priority. As shown below:
(5) threadgroup[name=g1,maxpri=8]
thread[a,9,g1]
THREAD[B,8,G1]
Therefore, the new thread cannot be changed to a level higher than the maximum thread group priority.
The default thread priority for this program is 6; If you create a new thread, that is its default priority, and it will not change unless you do something special with the priority. Practice VI will drop the maximum priority of the thread group below the default thread priority to see what happens when a new thread is created in this situation:
(6) threadgroup[name=g1,maxpri=3]
thread[a,9,g1]
thread[b,8,g1]
THREAD[C,6,G1]
Although the thread group now has a maximum priority of 3, it still creates a new thread with the default priority 6来. Therefore, the maximum priority of the thread group does not affect the default priority (in fact, there seems to be no way to set the default priority for the new thread).
After you have changed the priority, try to lower it one level, and the results are as follows:
(7) threadgroup[name=g1,maxpri=3]
thread[a,9,g1]
thread[b,8,g1]
THREAD[C,3,G1]
Therefore, the limit on the maximum priority of the thread group is enforced only when an attempt is made to change the priority level.
We conducted a similar experiment in (8) and (9). Here, we create a new thread group, called G2, as a subgroup of the G1 and change its maximum priority. As you can see, the priority of G2 cannot be higher than G1 at any rate:
(8) threadgroup[name=g2,maxpri=3]
(9) threadgroup[name=g2,maxpri=3]
Also note that when G2 is created, it is automatically set to the maximum priority of the G1 thread group.
After all these experiments, the entire thread group and the threading system are printed, as follows:
(10) THREADGROUP[NAME=SYSTEM,MAXPRI=9]
Thread[main,6,system]
threadgroup[name=g1,maxpri=3]
Thread[A, 9,G1]
THREAD[B,8,G1]
thread[c,3,g1]
threadgroup[name=g2,maxpri=3]
thread[0,6,g2]
THREAD[1,6,G2]
thread[2,6,g2]
thread[3,6,g2]
thread[4,6,g2]
Therefore, the rules of a thread group limit the maximum priority of a subgroup to at any time be less than or equal to the maximum priority of its parent group.
The last part of this program shows the method for the entire set of threads. The program first iterates through the entire thread tree and starts each thread that has not yet started. For example, the system group will then be suspended (paused) and finally aborted (although it may seem interesting to use suspend () and stop () for the entire thread group, it should be noted that these methods are "objected" to in Java 1.2). However, the main thread is suspended while the system group is suspended, and the entire program is closed. So it never reaches the point where the thread stops. In fact, if the main thread is really aborted, it "throws" a threaddeath violation, so we usually don't. Because Threadgroup is inherited from object, which contains the wait () method, you can also call a (number of seconds x1000) so that the program pauses to run any number of seconds. Of course, the object lock must be acquired in a synchronized block beforehand.
The Threadgroup class also provides the suspend () and resume () method, so it can abort and start the entire thread group and all its threads, and it can abort and start its subgroups, all with one command (again, suspend () and resume () Are all "opposed" by Java 1.2.
On the surface, thread groups seem to be a bit confusing, but note that we rarely need to use them directly.