線程的優先級(Priority)告訴調試程序該線程的重要程度有多大。如果有大量線程都被堵塞,都在等候運行,調試程序會首先運行具有優先級的那個線程。然而,這并不表示優先級較低的線程不會運行(換言之,不會因為存在優先級而導致死鎖)。若線程的優先級較低,只不過表示它被準許運行的機會小一些而已。
可用getPriority()方法讀取一個線程的優先級,并用setPriority()改變它。在下面這個程序片中,大家會發現計數器的計數速度慢了下來,因為它們關聯的線程分配了較低的優先級:
//: Counter5.java
// Adjusting the priorities of threads
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
class Ticker2 extends Thread {
private Button
b = new Button("Toggle"),
incPriority = new Button("up"),
decPriority = new Button("down");
private TextField
t = new TextField(10),
pr = new TextField(3); // Display priority
private int count = 0;
private boolean runFlag = true;
public Ticker2(Container c) {
b.addActionListener(new ToggleL());
incPriority.addActionListener(new UpL()); decPriority.addActionListener(new DownL());
Panel p = new Panel();
p.add(t);
p.add(pr);
p.add(b);
p.add(incPriority);
p.add(decPriority);
c.add(p);
}
class ToggleL implements ActionListener {
public void actionPerformed(ActionEvent e) {
runFlag = !runFlag;
}
}
class UpL implements ActionListener {
public void actionPerformed(ActionEvent e) {
int newPriority = getPriority() + 1;
if(newPriority > Thread.MAX_PRIORITY)
newPriority = Thread.MAX_PRIORITY;
setPriority(newPriority);
}
}
class DownL implements ActionListener {
public void actionPerformed(ActionEvent e) {
int newPriority = getPriority() - 1;
if(newPriority < Thread.MIN_PRIORITY)
newPriority = Thread.MIN_PRIORITY;
setPriority(newPriority);
}
}
public void run() {
while (true) {
if(runFlag) {
t.setText(Integer.toString(count++));
pr.setText(
Integer.toString(getPriority()));
}
yield();
}
}
}
public class Counter5 extends Applet {
private Button
start = new Button("Start"),
upMax = new Button("Inc Max Priority"),
downMax = new Button("Dec Max Priority");
private boolean started = false;
private static final int SIZE = 10;
private Ticker2[] s = new Ticker2[SIZE];
private TextField mp = new TextField(3);
public void init() {
for(int i = 0; i < s.length; i++)
s[i] = new Ticker2(this);
add(new Label("MAX_PRIORITY = "
+ Thread.MAX_PRIORITY));
add(new Label("MIN_PRIORITY = "
+ Thread.MIN_PRIORITY));
add(new Label("Group Max Priority = "));
add(mp);
add(start);
add(upMax); add(downMax);
start.addActionListener(new StartL());
upMax.addActionListener(new UpMaxL());
downMax.addActionListener(new DownMaxL());
showMaxPriority();
// Recursively display parent thread groups:
ThreadGroup parent =
s[0].getThreadGroup().getParent();
while(parent != null) {
add(new Label(
"Parent threadgroup max priority = "
+ parent.getMaxPriority()));
parent = parent.getParent();
}
}
public void showMaxPriority() {
mp.setText(Integer.toString(
s[0].getThreadGroup().getMaxPriority()));
}
class StartL implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(!started) {
started = true;
for(int i = 0; i < s.length; i++)
s[i].start();
}
}
}
class UpMaxL implements ActionListener {
public void actionPerformed(ActionEvent e) {
int maxp =
s[0].getThreadGroup().getMaxPriority();
if(++maxp > Thread.MAX_PRIORITY)
maxp = Thread.MAX_PRIORITY;
s[0].getThreadGroup().setMaxPriority(maxp);
showMaxPriority();
}
}
class DownMaxL implements ActionListener {
public void actionPerformed(ActionEvent e) {
int maxp =
s[0].getThreadGroup().getMaxPriority();
if(--maxp < Thread.MIN_PRIORITY)
maxp = Thread.MIN_PRIORITY;
s[0].getThreadGroup().setMaxPriority(maxp);
showMaxPriority();
}
}
public static void main(String[] args) {
Counter5 applet = new Counter5();
Frame aFrame = new Frame("Counter5");
aFrame.addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
aFrame.add(applet, BorderLayout.CENTER);
aFrame.setSize(300, 600);
applet.init();
applet.start();
aFrame.setVisible(true);
}
} ///:~
Ticker采用本章前面構造好的形式,但有一個額外的TextField(文本字段),用于顯示線程的優先級;以及兩個額外的按鈕,用于人為提高及降低優先級。
也要注意yield()的用法,它將控制權自動返回給調試程序(機制)。若不進行這樣的處理,多線程機制仍會工作,但我們會發現它的運行速度慢了下來(試試刪去對yield()的調用)。亦可調用sleep(),但假若那樣做,計數頻率就會改由sleep()的持續時間控制,而不是優先級。
Counter5中的init()創建了由10個Ticker2構成的一個數組;它們的按鈕以及輸入字段(文本字段)由Ticker2構建器置入窗體。Counter5增加了新的按鈕,用于啟動一切,以及用于提高和降低線程組的優先級。除此以外,還有一些標簽用于顯示一個線程可以采用的及小優先級;以及一個特殊的文本字段,用于顯示線程組的優先級。,父線程組的優先級也作為標簽顯示出來。
按下“up”(上)或“down”(下)按鈕的時候,會先取得Ticker2當前的優先級,然后相應地提高或者降低。
運行該程序時,我們可注意到幾件事情。首先,線程組的默認優先級是5。即使在啟動線程之前(或者在創建線程之前,這要求對代碼進行適當的修改)將優先級降到5以下,每個線程都會有一個5的默認優先級。
簡單的測試是獲取一個計數器,將它的優先級降低至1,此時應觀察到它的計數頻率顯著放慢。現在試著再次提高優先級,可以升高回線程組的優先級,但不能再高了。現在將線程組的優先級降低兩次。線程的優先級不會改變,但假若試圖提高或者降低它,就會發現這個優先級自動變成線程組的優先級。此外,新線程仍然具有一個默認優先級,即使它比組的優先級還要高(換句話說,不要指望利用組優先級來防止新線程擁有比現有的更高的優先級)。
,試著提高組的優先級。可以發現,這樣做是沒有效果的。我們只能減少線程組的優先級,而不能增大它。
Java多線程的優先級
更新時間: 2007-06-06 14:11:37來源: 粵嵌教育瀏覽量:496