📄 tij0158.html
字号:
<html><body>
<table width="100%"><tr>
<td>
<a href="http://www.bruceeckel.com/javabook.html">Bruce Eckel's Thinking in Java</a>
</td>
<td align="right">
<a href="tij_c.html">Contents</a> | <a href="tij0157.html">Prev</a> | <a href="tij0159.html">Next</a>
</td>
</tr></table>
<hr>
<H2 ALIGN=LEFT>
Priorities</H2>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
<A NAME="Index2593"></A><A NAME="Index2594"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><I>priority</I></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
of a thread tells the scheduler how important this thread is. If there are a
number of threads blocked and waiting to be run, the scheduler will run the one
with the highest priority first. However, this doesn’t mean that threads
with lower priority don’t get run (that is, you can’t get
deadlocked because of priorities). Lower priority threads just tend to run less
often.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">You
can read the priority of a thread with <A NAME="Index2595"></A><A NAME="Index2596"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>getPriority( )
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">and
change it with <A NAME="Index2597"></A><A NAME="Index2598"></A></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>setPriority( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">.
The form of the prior “counter” examples can be used to show the
effect of changing the priorities. In this applet you’ll see that the
counters slow down as the associated threads have their priorities lowered:
</FONT><P></DIV>
<font color="#990000"><PRE><font color="#009900">//: Counter5.java</font>
<font color="#009900">// Adjusting the priorities of threads</font>
<font color="#0000ff">import</font> java.awt.*;
<font color="#0000ff">import</font> java.awt.event.*;
<font color="#0000ff">import</font> java.applet.*;
<font color="#0000ff">class</font> Ticker2 <font color="#0000ff">extends</font> Thread {
<font color="#0000ff">private</font> Button
b = <font color="#0000ff">new</font> Button("Toggle"),
incPriority = <font color="#0000ff">new</font> Button("up"),
decPriority = <font color="#0000ff">new</font> Button("down");
<font color="#0000ff">private</font> TextField
t = <font color="#0000ff">new</font> TextField(10),
pr = <font color="#0000ff">new</font> TextField(3); <font color="#009900">// Display priority</font>
<font color="#0000ff">private</font> <font color="#0000ff">int</font> count = 0;
<font color="#0000ff">private</font> <font color="#0000ff">boolean</font> runFlag = <font color="#0000ff">true</font>;
<font color="#0000ff">public</font> Ticker2(Container c) {
b.addActionListener(<font color="#0000ff">new</font> ToggleL());
incPriority.addActionListener(<font color="#0000ff">new</font> UpL());
decPriority.addActionListener(<font color="#0000ff">new</font> DownL());
Panel p = <font color="#0000ff">new</font> Panel();
p.add(t);
p.add(pr);
p.add(b);
p.add(incPriority);
p.add(decPriority);
c.add(p);
}
<font color="#0000ff">class</font> ToggleL <font color="#0000ff">implements</font> ActionListener {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e) {
runFlag = !runFlag;
}
}
<font color="#0000ff">class</font> UpL <font color="#0000ff">implements</font> ActionListener {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e) {
<font color="#0000ff">int</font> newPriority = getPriority() + 1;
<font color="#0000ff">if</font>(newPriority > Thread.MAX_PRIORITY)
newPriority = Thread.MAX_PRIORITY;
setPriority(newPriority);
}
}
<font color="#0000ff">class</font> DownL <font color="#0000ff">implements</font> ActionListener {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e) {
<font color="#0000ff">int</font> newPriority = getPriority() - 1;
<font color="#0000ff">if</font>(newPriority < Thread.MIN_PRIORITY)
newPriority = Thread.MIN_PRIORITY;
setPriority(newPriority);
}
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> run() {
<font color="#0000ff">while</font> (<font color="#0000ff">true</font>) {
<font color="#0000ff">if</font>(runFlag) {
t.setText(Integer.toString(count++));
pr.setText(
Integer.toString(getPriority()));
}
yield();
}
}
}
<font color="#0000ff">public</font> <font color="#0000ff">class</font> Counter5 <font color="#0000ff">extends</font> Applet {
<font color="#0000ff">private</font> Button
start = <font color="#0000ff">new</font> Button("Start"),
upMax = <font color="#0000ff">new</font> Button("Inc Max Priority"),
downMax = <font color="#0000ff">new</font> Button("Dec Max Priority");
<font color="#0000ff">private</font> <font color="#0000ff">boolean</font> started = <font color="#0000ff">false</font>;
<font color="#0000ff">private</font> <font color="#0000ff">static</font> <font color="#0000ff">final</font> <font color="#0000ff">int</font> SIZE = 10;
<font color="#0000ff">private</font> Ticker2[] s = <font color="#0000ff">new</font> Ticker2[SIZE];
<font color="#0000ff">private</font> TextField mp = <font color="#0000ff">new</font> TextField(3);
<font color="#0000ff">public</font> <font color="#0000ff">void</font> init() {
<font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i < s.length; i++)
s[i] = <font color="#0000ff">new</font> Ticker2(<font color="#0000ff">this</font>);
add(<font color="#0000ff">new</font> Label("MAX_PRIORITY = "
+ Thread.MAX_PRIORITY));
add(<font color="#0000ff">new</font> Label("MIN_PRIORITY = "
+ Thread.MIN_PRIORITY));
add(<font color="#0000ff">new</font> Label("Group Max Priority = "));
add(mp);
add(start);
add(upMax); add(downMax);
start.addActionListener(<font color="#0000ff">new</font> StartL());
upMax.addActionListener(<font color="#0000ff">new</font> UpMaxL());
downMax.addActionListener(<font color="#0000ff">new</font> DownMaxL());
showMaxPriority();
<font color="#009900">// Recursively display parent thread groups:</font>
ThreadGroup parent =
s[0].getThreadGroup().getParent();
<font color="#0000ff">while</font>(parent != <font color="#0000ff">null</font>) {
add(<font color="#0000ff">new</font> Label(
"Parent threadgroup max priority = "
+ parent.getMaxPriority()));
parent = parent.getParent();
}
}
<font color="#0000ff">public</font> <font color="#0000ff">void</font> showMaxPriority() {
mp.setText(Integer.toString(
s[0].getThreadGroup().getMaxPriority()));
}
<font color="#0000ff">class</font> StartL <font color="#0000ff">implements</font> ActionListener {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e) {
<font color="#0000ff">if</font>(!started) {
started = <font color="#0000ff">true</font>;
<font color="#0000ff">for</font>(<font color="#0000ff">int</font> i = 0; i < s.length; i++)
s[i].start();
}
}
}
<font color="#0000ff">class</font> UpMaxL <font color="#0000ff">implements</font> ActionListener {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e) {
<font color="#0000ff">int</font> maxp =
s[0].getThreadGroup().getMaxPriority();
<font color="#0000ff">if</font>(++maxp > Thread.MAX_PRIORITY)
maxp = Thread.MAX_PRIORITY;
s[0].getThreadGroup().setMaxPriority(maxp);
showMaxPriority();
}
}
<font color="#0000ff">class</font> DownMaxL <font color="#0000ff">implements</font> ActionListener {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> actionPerformed(ActionEvent e) {
<font color="#0000ff">int</font> maxp =
s[0].getThreadGroup().getMaxPriority();
<font color="#0000ff">if</font>(--maxp < Thread.MIN_PRIORITY)
maxp = Thread.MIN_PRIORITY;
s[0].getThreadGroup().setMaxPriority(maxp);
showMaxPriority();
}
}
<font color="#0000ff">public</font> <font color="#0000ff">static</font> <font color="#0000ff">void</font> main(String[] args) {
Counter5 applet = <font color="#0000ff">new</font> Counter5();
Frame aFrame = <font color="#0000ff">new</font> Frame("Counter5");
aFrame.addWindowListener(
<font color="#0000ff">new</font> WindowAdapter() {
<font color="#0000ff">public</font> <font color="#0000ff">void</font> windowClosing(WindowEvent e) {
System.exit(0);
}
});
aFrame.add(applet, BorderLayout.CENTER);
aFrame.setSize(300, 600);
applet.init();
applet.start();
aFrame.setVisible(<font color="#0000ff">true</font>);
}
} <font color="#009900">///:~ </PRE></font></font><DIV ALIGN=LEFT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Ticker2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
follows the form established earlier in this chapter, but there’s an extra
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TextField</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
for displaying the priority of the thread and two more buttons for incrementing
and decrementing the priority.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Also
notice the use of
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>yield( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
which voluntarily hands control back to the scheduler. Without this the
multithreading mechanism still works, but you’ll notice it runs slowly
(try removing the call to
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>yield( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">!).
You could also call
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">,
but then the rate of counting would be controlled by the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>sleep( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
duration instead of the priority.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>init( )</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
in
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Counter5</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
creates an array of 10
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Ticker2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">s;
their buttons and fields are placed on the form by the
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Ticker2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
constructor.
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Counter5
</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">adds
buttons to start everything up as well as increment and decrement the maximum
priority of the threadgroup. In addition, there are labels that display the
maximum and minimum priorities possible for a thread and a
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>TextField</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">
to show the thread group’s maximum priority. (The next section will fully
describe thread groups.) Finally, the priorities of the parent thread groups
are also displayed as labels.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
you press an “up” or “down” button, that
</FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black"><B>Ticker2</B></FONT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">’s
priority is fetched and incremented or decremented accordingly.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">When
you run this program, you’ll notice several things. First of all, the
thread group’s <A NAME="Index2599"></A><A NAME="Index2600"></A>default
priority is 5. Even if you decrement the maximum priority below 5 before
starting the threads (or before creating the threads, which requires a code
change), each thread will have a default priority of 5.
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">The
simple test is to take one counter and decrement its priority to one, and
observe that it counts much slower. But now try to increment it again. You can
get it back up to the thread group’s priority, but no higher. Now
decrement the thread group’s priority a couple of times. The thread
priorities are unchanged, but if you try to modify them either up or down
you’ll see that they’ll automatically pop to the priority of the
thread group. Also, new threads will still be given a default priority, even if
that’s higher than the group priority. (Thus the group priority is not a
way to prevent new threads from having higher priorities than existing ones.)
</FONT><P></DIV><DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">Finally,
try to increment the group maximum priority. It can’t be done. You can
only reduce thread group maximum priorities, not increase them.
</FONT><a name="_Toc375545485"></a><a name="_Toc408018759"></a><P></DIV>
<A NAME="Heading505"></A><H3 ALIGN=LEFT>
Thread
groups
</H3>
<DIV ALIGN=LEFT><FONT FACE="Carmina Md BT" SIZE=3 COLOR="Black">All
threads belong to a <A NAME="Index2601"></A>thread
group. This can be either the default thread group or a group you explicitly
specify when you create the thread. At creation, the thread is bound to a group
and cannot change to a different group. Each application has at least one
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -