📄 tij0158.html
字号:
thread that belongs to the system thread group. If you create more threads
without specifying a group, they will also belong to the system thread group.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Thread
groups must also belong to other thread groups. The thread group that a new one
belongs to must be specified in the constructor. If you create a thread group
without specifying a thread group for it to belong to, it will be placed under
the system thread group. Thus, all thread groups in your application will
ultimately have the system thread group as the parent.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
reason for the existence of thread groups is hard to determine from the
literature, which tends to be confusing on this subject. It’s often cited
as “security reasons.” According to Arnold & Gosling,
</FONT><A NAME="fnB62" HREF="#fn62">[62]</A><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
“Threads within a thread group can modify the other threads in the group,
including any farther down the hierarchy. A thread cannot modify threads
outside of its own group or contained groups.” It’s hard to know
what “modify” is supposed to mean here. The following example shows
a thread in a “leaf” subgroup modifying the priorities of all the
threads in its tree of thread groups as well as calling a method for all the
threads in its tree.
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: TestAccess.java</font>
<font color="#009900">// How threads can access other threads</font>
<font color="#009900">// in a parent thread group</font>
<font color="#0000ff">public</font> <font color="#0000ff">class</font> TestAccess {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
ThreadGroup
x = <font color="#0000ff">new</font> ThreadGroup("x"),
y = <font color="#0000ff">new</font> ThreadGroup(x, "y"),
z = <font color="#0000ff">new</font> ThreadGroup(y, "z");
Thread
one = <font color="#0000ff">new</font> TestThread1(x, "one"),
two = <font color="#0000ff">new</font> TestThread2(z, "two");
}
}
<font color="#0000ff">class</font> TestThread1 <font color="#0000ff">extends</font> Thread {
<font color="#0000ff">private</font> <font color="#0000ff">int</font> i;
TestThread1(ThreadGroup g, String name) {
<font color="#0000ff">super</font>(g, name);
}
<font color="#0000ff">void</font> f() {
i++; <font color="#009900">// modify this thread</font>
System.out.println(getName() + " f()");
}
}
<font color="#0000ff">class</font> TestThread2 <font color="#0000ff">extends</font> TestThread1 {
TestThread2(ThreadGroup g, String name) {
<font color="#0000ff">super</font>(g, name);
start();
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> run() {
ThreadGroup g =
getThreadGroup().getParent().getParent();
g.list();
Thread[] gAll = <font color="#0000ff">new</font> Thread[g.activeCount()];
g.enumerate(gAll);
<font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i < gAll.length; i++) {
gAll[i].setPriority(Thread.MIN_PRIORITY);
((TestThread1)gAll[i]).f();
}
g.list();
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">In
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>main( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
several
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ThreadGroup</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
are created, leafing off from each other:
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>x</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
has no argument but its name (a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>String</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">),
so it is automatically placed in the “system” thread group, while
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>y</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is under
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>x</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>z</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is under
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>y</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
Note that initialization happens in textual order so this code is legal.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Two
threads are created and placed in different thread groups.
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TestThread1</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
doesn’t have a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method but it does have an
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>f( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
that modifies the thread and prints something so you can see it was called.
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TestThread2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is a subclass of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TestThread1</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
and its
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is fairly elaborate. It first gets the thread group of the current thread, then
moves up the heritage tree by two levels using
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getParent( ).</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
(This is contrived since I purposely place the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TestThread2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
object two levels down in the hierarchy.) At this point, an array of handles to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s
is created using the method
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>activeCount( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to ask how many threads are in this thread group and all the child thread
groups. The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>enumerate( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method places handles to all of these threads in the array
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>gAll</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
then I simply move through the entire array calling the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>f( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method for each thread, as well as modifying the priority. Thus, a thread in a
“leaf” thread group modifies threads in parent thread groups.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
debugging method
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>list( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
prints all the information about a thread group to standard output and is
helpful when investigating thread group behavior. Here’s the output of
the program:
</FONT><P></DIV>
<font color="#990000"><PRE>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] </PRE></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Not
only does
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>list( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
print the class name of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>ThreadGroup</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
or
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Thread</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
but it also prints the thread group name and its maximum priority. For threads,
the thread name is printed, followed by the thread priority and the group that
it belongs to. Note that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>list( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
indents the threads and thread groups to indicate that they are children of the
un-indented thread group.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can see that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>f( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
is called by the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TestThread2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>run( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
method, so it’s obvious that all threads in a group are vulnerable.
However, you can access only the threads that branch off from your own
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>system</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
thread group tree, and perhaps this is what is meant by “safety.”
You cannot access anyone else’s system thread group tree.
</FONT><P></DIV>
<A NAME="Heading506"></A><H4 ALIGN=LEFT>
Controlling
thread groups
</H4>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Putting
aside the safety issue, one thing thread groups do seem to be useful for is
control: you can perform certain operations on an entire thread group with a
single command. The following example demonstrates this and the restrictions on
priorities within thread groups. The commented numbers in parentheses provide a
reference to compare to the output.
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: ThreadGroup1.java</font>
<font color="#009900">// How thread groups control priorities</font>
<font color="#009900">// of the threads inside them.</font>
<font color="#0000ff">public</font> <font color="#0000ff">class</font> ThreadGroup1 {
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
<font color="#009900">// Get the system thread & print its Info:</font>
ThreadGroup sys =
Thread.currentThread().getThreadGroup();
sys.list(); <font color="#009900">// (1)</font>
<font color="#009900">// Reduce the system thread group priority:</font>
sys.setMaxPriority(Thread.MAX_PRIORITY - 1);
<font color="#009900">// Increase the main thread priority:</font>
Thread curr = Thread.currentThread();
curr.setPriority(curr.getPriority() + 1);
sys.list(); <font color="#009900">// (2)</font>
<font color="#009900">// Attempt to set a new group to the max:</font>
ThreadGroup g1 = <font color="#0000ff">new</font> ThreadGroup("g1");
g1.setMaxPriority(Thread.MAX_PRIORITY);
<font color="#009900">// Attempt to set a new thread to the max:</font>
Thread t = <font color="#0000ff">new</font> Thread(g1, "A");
t.setPriority(Thread.MAX_PRIORITY);
g1.list(); <font color="#009900">// (3)</font>
<font color="#009900">// Reduce g1's max priority, then attempt</font>
<font color="#009900">// to increase it:</font>
g1.setMaxPriority(Thread.MAX_PRIORITY - 2);
g1.setMaxPriority(Thread.MAX_PRIORITY);
g1.list(); <font color="#009900">// (4)</font>
<font color="#009900">// Attempt to set a new thread to the max:</font>
t = <font color="#0000ff">new</font> Thread(g1, "B");
t.setPriority(Thread.MAX_PRIORITY);
g1.list(); <font color="#009900">// (5)</font>
<font color="#009900">// Lower the max priority below the default</font>
<font color="#009900">// thread priority:</font>
g1.setMaxPriority(Thread.MIN_PRIORITY + 2);
<font color="#009900">// Look at a new thread's priority before</font>
<font color="#009900">// and after changing it:</font>
t = <font color="#0000ff">new</font> Thread(g1, "C");
g1.list(); <font color="#009900">// (6)</font>
t.setPriority(t.getPriority() -1);
g1.list(); <font color="#009900">// (7)</font>
<font color="#009900">// Make g2 a child Threadgroup of g1 and</font>
<font color="#009900">// try to increase its priority:</font>
ThreadGroup g2 = <font color="#0000ff">new</font> ThreadGroup(g1, "g2");
g2.list(); <font color="#009900">// (8)</font>
g2.setMaxPriority(Thread.MAX_PRIORITY);
g2.list(); <font color="#009900">// (9)</font>
<font color="#009900">// Add a bunch of new threads to g2:</font>
<font color="#0000ff">for</font> (<font color="#0000ff">int</font> i = 0; i < 5; i++)
<font color="#0000ff">new</font> Thread(g2, Integer.toString(i));
<font color="#009900">// Show information about all threadgroups</font>
<font color="#009900">// and threads:</font>
sys.list(); <font color="#009900">// (10)</font>
System.out.println("Starting all threads:");
Thread[] all = <font color="#0000ff">new</font> Thread[sys.activeCount()];
sys.enumerate(all);
<font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i < all.length; i++)
<font color="#0000ff">if</font>(!all[i].isAlive())
all[i].start();
<font color="#009900">// Suspends & Stops all threads in </font>
<font color="#009900">// this group and its subgroups:</font>
System.out.println("All threads started");
sys.suspend(); <font color="#009900">// Deprecated in Java 1.2</font>
<font color="#009900">// Never gets here...</font>
System.out.println("All threads suspended");
sys.stop(); <font color="#009900">// Deprecated in Java 1.2</font>
System.out.println("All threads stopped");
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
output that follows has been edited to allow it to fit on the page (the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>java.lang.</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
has been removed) and to add numbers to correspond to the commented numbers in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -