友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
狗狗书籍 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

Java编程思想第4版[中文版](PDF格式)-第224章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!




          Integer。toString(getPriority()));  

      }  



                                                                                          522 


…………………………………………………………Page 524……………………………………………………………

      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 = fal se;  

  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();  

      }  

    }  

  }  



                                                                                             523 


…………………………………………………………Page 525……………………………………………………………

  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 的默认优先 

级。  



                                                                                          524 


…………………………………………………………Page 526……………………………………………………………

最简单的测试是获取一个计数器,将它的优先级降低至 1,此时应观察到它的计数频率显著放慢。现在试着 

再次提高优先级,可以升高回线程组的优先级,但不能再高了。现在将线程组的优先级降低两次。线程的优 

先级不会改变,但假若试图提高或者降低它,就会发现这个优先级自动变成线程组的优先级。此外,新线程 

仍然具有一个默认优先级,即使它比组的优先级还要高(换句话说,不要指望利用组优先级来防止新线程拥 

有比现有的更高的优先级)。  

最后,试着提高组的最大优先级。可以发现,这样做是没有效果的。我们只能减少线程组的最大优先级,而 

不能增大它。  



14。4。1 线程组  



所有线程都隶属于一个线程组。那可以是一个默认线程组,亦可是一个创建线程时明确指定的组。在创建之 

初,线程被限制到一个组里,而且不能改变到一个不同的组。每个应用都至少有一个线程从属于系统线程 

组。若创建多个线程而不指定一个组,它们就会自动归属于系统线程组。  

线程组也必须从属于其他线程组。必须在构建器里指定新线程组从属于哪个线程组。若在创建一个线程组的 

时候没有指定它的归属,则同样会自动成为系统线程组的一名属下。因此,一个应用程序中的所有线程组最 

终都会将系统线程组作为自己的“父”。  

之所以要提出“线程组”的概念,很难从字面上找到原因。这多少为我们讨论的主题带来了一些混乱。一般 

地说,我们认为是由于“安全”或者“保密”方面的理由才使用线程组的。根据 Arnold 和 Gosling 的说法: 

 “线程组中的线程可以修改组内的其他线程,包括那些位于分层结构最深处的。一个线程不能修改位于自己 

所在组或者下属组之外的任何线程”(注释①)。然而,我们很难判断“修改”在这儿的具体含义是什么。 

下面这个例子展示了位于一个“叶子组”内的线程能修改它所在线�
返回目录 上一页 下一页 回到顶部 赞(1) 踩(1)
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!