国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

制作多個線程

2019-11-18 12:20:57
字體:
來源:轉載
供稿:網友

  現在考慮一下創建多個不同的線程的問題。我們不可用前面的例子來做到這一點,所以必須倒退回去,利用從Thread繼續的多個獨立類來封裝run()。但這是一種更常規的方案,而且更易理解,所以盡管前例揭示了我們經常都能看到的編碼樣式,但并不推薦在大多數情況下都那樣做,因為它只是稍微復雜一些,而且靈活性稍低一些。
  下面這個例子用計數器和切換按鈕再現了前面的編碼樣式。但這一次,一個特定計數器的所有信息(按鈕和文本字段)都位于它自己的、從Thread繼續的對象內。Ticker中的所有字段都具有PRivate(私有)屬性,這意味著Ticker的具體實現方案可根據實際情況任意修改,其中包括修改用于獲取和顯示信息的數據組件的數量及類型。創建好一個Ticker對象以后,構建器便請求一個AWT容器(Container)的句柄——Ticker用自己的可視組件填充那個容器。采用這種方式,以后一旦改變了可視組件,使用Ticker的代碼便不需要另行修改一道。
  //: Counter4.java
  // If you separate your thread from the main
  // class, you can have as many threads as you
  // want.
  import java.awt.*;
  import java.awt.event.*;
  import java.applet.*;
  class Ticker extends Thread {
   private Button b = new Button("Toggle");
   private TextField t = new TextField(10);
   private int count = 0;
   private boolean runFlag = true;
   public Ticker(Container c) {
   b.addActionListener(new ToggleL());
   Panel p = new Panel();
   p.add(t);
   p.add(b);
   c.add(p);
   }
   class ToggleL implements ActionListener {
   public void actionPerformed(ActionEvent e) {
   runFlag = !runFlag;
   }
   }
   public void run() {
   while (true) {
   if(runFlag)
   t.setText(Integer.toString(count++));
   try {
   sleep(100);
   } catch (InterruptedException e){}
   }
   }
  }
  public class Counter4 extends Applet {
   private Button start = new Button("Start");
   private boolean started = false;
   private Ticker[] s;
   private boolean isApplet = true;
   private int size;
   public void init() {
   // Get parameter "size" from Web page:
   if(isApplet)
   size =
   Integer.parseInt(getParameter("size"));
   s = new Ticker[size];
   for(int i = 0; i < s.length; i++)
   s[i] = new Ticker(this);
   start.addActionListener(new StartL());
   add(start);
   }
   class StartL implements ActionListener {
   public void actionPerformed(ActionEvent e) {
   if(!started) {
   started = true;
   for(int i = 0; i < s.length; i++)
   s[i].start();
   }
   }
   }
   public static void main(String[] args) {
   Counter4 applet = new Counter4();
   // This isn't an applet, so set the flag and
   // prodUCe the parameter values from args:
   applet.isApplet = false;
   applet.size =
   (args.length == 0 ? 5 :
   Integer.parseInt(args[0]));
   Frame aFrame = new Frame("Counter4");
   aFrame.addWindowListener(
   new WindowAdapter() {
   public void windowClosing(WindowEvent e) {
   System.exit(0);
   }
   });
   aFrame.add(applet, BorderLayout.CENTER);
   aFrame.setSize(200, applet.size * 50);
   applet.init();
   applet.start();
   aFrame.setVisible(true);
   }
  }
  Ticker不僅包括了自己的線程處理機制,也提供了控制與顯示線程的工具。可按自己的意愿創建任意數量的線程,毋需明確地創建窗口化組件。
  在Counter4中,有一個名為s的Ticker對象的數組。為獲得最大的靈活性,這個數組的長度是用程序片參數接觸Web頁而初始化的。下面是網頁中長度參數大致的樣子,它們嵌于對程序片(applet)的描述內容中:
  
  
  
  其中,param,name和value是所有Web頁都適用的要害字。name是指程序中對參數的一種引用稱謂,value可以是任何字串(并不僅僅是解析成一個數字的東西)。
  我們注重到對數組s長度的判定是在init()內部完成的,它沒有作為s的內嵌定義的一部分提供。換言之,不可將下述代碼作為類定義的一部分使用(應該位于任何方法的外部):
  inst size = Integer.parseInt(getParameter("Size"));
  Ticker[] s = new Ticker[size]
  可把它編譯出來,但會在運行期得到一個空指針違例。但若將getParameter()初始化移入init(),則可正常工作。程序片框架會進行必要的啟動工作,以便在進入init()前收集好一些參數。
  此外,上述代碼被同時設置成一個程序片和一個應用(程序)。在它是應用程序的情況下,size參數可從命令行里提取出來(否則就提供一個默認的值)。
  數組的長度建好以后,就可以創建新的Ticker對象;作為Ticker構建器的一部分,用于每個Ticker的按鈕和文本字段就會加入程序片。
  按下Start按鈕后,會在整個Ticker數組里遍歷,并為每個Ticker調用start()。記住,start()會進行必要的線程初始化工作,然后為那個線程調用run()。
  ToggleL監視器只是簡單地切換Ticker中的標記,一旦對應線程以后需要修改這個標記,它會作出相應的反應。
  這個例子的一個好處是它使我們能夠方便地創建由單獨子任務構成的大型集合,并以監視它們的行為。在這種情況下,我們會發現隨著子任務數量的增多,機器顯示出來的數字可能會出現更大的分歧,這是由于為線程提供服務的方式造成的。
  亦可試著體驗一下sleep(100)在Ticker.run()中的重要作用。若刪除sleep(),那么在按下一個切換按鈕前,情況仍然會進展良好。按下按鈕以后,那個特定的線程就會出現一個失敗的runFlag,而且run()會深深地陷入一個無限循環——很難在多任務處理期間中止退出。因此,程序對用戶操作的反應靈敏度會大幅度降低。

上一篇:多線程

下一篇:用主類合并線程

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 敦化市| 隆安县| 鄱阳县| 绥宁县| 萝北县| 临汾市| 陆川县| 通州区| 璧山县| 长寿区| 织金县| 即墨市| 三河市| 岳普湖县| 青冈县| 星座| 鹤峰县| 阳谷县| 安阳市| 乌鲁木齐县| 电白县| 靖州| 泸定县| 香河县| 西丰县| 中山市| 新晃| 贺州市| 工布江达县| 隆安县| 广灵县| 达日县| 泸水县| 万州区| 运城市| 定边县| 邢台县| 文成县| 莱阳市| 沂南县| 兴宁市|