熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java高級技術 >> 正文

Java多線程的優先級

2013-11-23 19:51:59  來源: Java高級技術 

  優先級
  線程的優先級(Priority)告訴調試程序該線程的重要程度有多大如果有大量線程都被堵塞都在等候運行調試程序會首先運行具有最高優先級的那個線程然而這並不表示優先級較低的線程不會運行(換言之不會因為存在優先級而導致死鎖)若線程的優先級較低只不過表示它被准許運行的機會小一些而已
  可用getPriority()方法讀取一個線程的優先級並用setPriority()改變它在下面這個程序片中大家會發現計數器的計數速度慢了下來因為它們關聯的線程分配了較低的優先級
  //: Counterjava
  // Adjusting the priorities of threads
  import javaawt*;
  import javaawtevent*;
  import javaapplet*;
  class Ticker extends Thread {
   private Button
   b = new Button(Toggle)
   incPriority = new Button(up)
   decPriority = new Button(down);
   private TextField
   t = new TextField()
   pr = new TextField(); // Display priority
   private int count = ;
   private boolean runFlag = true;
   public Ticker(Container c) {
   baddActionListener(new ToggleL());
   incPriorityaddActionListener(new UpL()); decPriorityaddActionListener(new DownL());
   Panel p = new Panel();
   padd(t);
   padd(pr);
   padd(b);
   padd(incPriority);
   padd(decPriority);
   cadd(p);
   }
   class ToggleL implements ActionListener {
   public void actionPerformed(ActionEvent e) {
   runFlag = !runFlag;
   }
   }
   class UpL implements ActionListener {
   public void actionPerformed(ActionEvent e) {
   int newPriority = getPriority() + ;
   if(newPriority > ThreadMAX_PRIORITY)
   newPriority = ThreadMAX_PRIORITY;
   setPriority(newPriority);
   }
   }
   class DownL implements ActionListener {
   public void actionPerformed(ActionEvent e) {
   int newPriority = getPriority() ;
   if(newPriority < ThreadMIN_PRIORITY)
   newPriority = ThreadMIN_PRIORITY;
   setPriority(newPriority);
   }
   }
   public void run() {
   while (true) {
   if(runFlag) {
   tsetText(IntegertoString(count++));
   prsetText(
   IntegertoString(getPriority()));
   }
   yield();
   }
   }
  }
  public class Counter 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 = ;
   private Ticker[] s = new Ticker[SIZE];
   private TextField mp = new TextField();
   public void init() {
   for(int i = ; 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(文本字段),用於顯示線程的優先級;以及兩個額外的按鈕,用於人為提高及降低優先級。TW.WInGWit.cOM
  也要注意yield()的用法,它將控制權自動返回給調試程序(機制)。若不進行這樣的處理,多線程機制仍會工作,但我們會發現它的運行速度慢了下來(試試刪去對yield()的調用)。亦可調用sleep(),但假若那樣做,計數頻率就會改由sleep()的持續時間控制,而不是優先級。
  Counter5中的init()創建了由10個Ticker2構成的一個數組;它們的按鈕以及輸入字段(文本字段)由Ticker2構建器置入窗體。Counter5增加了新的按鈕,用於啟動一切,以及用於提高和降低線程組的最大優先級。除此以外,還有一些標簽用於顯示一個線程可以采用的最大及最小優先級;以及一個特殊的文本字段,用於顯示線程組的最大優先級(在下一節裡,我們將全面討論線程組的問題)。最後,父線程組的優先級也作為標簽顯示出來。
  按下“up”(上)或“down”(下)按鈕的時候,會先取得Ticker2當前的優先級,然後相應地提高或者降低。
  運行該程序時,我們可注意到幾件事情。首先,線程組的默認優先級是5。即使在啟動線程之前(或者在創建線程之前,這要求對代碼進行適當的修改)將最大優先級降到5以下,每個線程都會有一個5的默認優先級。
  最簡單的測試是獲取一個計數器,將它的優先級降低至1,此時應觀察到它的計數頻率顯著放慢。現在試著再次提高優先級,可以升高回線程組的優先級,但不能再高了。現在將線程組的優先級降低兩次。線程的優先級不會改變,但假若試圖提高或者降低它,就會發現這個優先級自動變成線程組的優先級。此外,新線程仍然具有一個默認優先級,即使它比組的優先級還要高(換句話說,不要指望利用組優先級來防止新線程擁有比現有的更高的優先級)。
  最後,試著提高組的最大優先級。可以發現,這樣做是沒有效果的。我們只能減少線程組的最大優先級,而不能增大它。

From:http://tw.wingwit.com/Article/program/Java/gj/201311/27587.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.