程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 用主類合並線程

用主類合並線程

編輯:關於JAVA

在上面的例子中,我們看到線程類(Thread)與程序的主類(Main)是分隔開的。這樣做非常合理,而且易於理解。然而,還有另一種方式也是經常要用到的。盡管它不十分明確,但一般都要更簡潔一些(這也解釋了它為什麼十分流行)。通過將主程序類變成一個線程,這種形式可將主程序類與線程類合並到一起。由於對一個GUI程序來說,主程序類必須從Frame或Applet繼承,所以必須用一個接口加入額外的功能。這個接口叫作Runnable,其中包含了與Thread一致的基本方法。事實上,Thread也實現了Runnable,它只指出有一個run()方法。
對合並後的程序/線程來說,它的用法不是十分明確。當我們啟動程序時,會創建一個Runnable(可運行的)對象,但不會自行啟動線程。線程的啟動必須明確進行。下面這個程序向我們演示了這一點,它再現了Counter2的功能:
 

//: Counter3.java
// Using the Runnable interface to turn the 
// main class into a thread.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class Counter3 
    extends Applet implements Runnable {
  private int count = 0;
  private boolean runFlag = true;
  private Thread selfThread = null;
  private Button 
    onOff = new Button("Toggle"),
    start = new Button("Start");
  private TextField t = new TextField(10);
  public void init() {
    add(t);
    start.addActionListener(new StartL());
    add(start);
    onOff.addActionListener(new OnOffL());
    add(onOff);
  }
  public void run() {
    while (true) {
      try {
        selfThread.sleep(100);
      } catch (InterruptedException e){}
      if(runFlag) 
        t.setText(Integer.toString(count++));
    }
  }
  class StartL implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      if(selfThread == null) {
        selfThread = new Thread(Counter3.this);
        selfThread.start();
      }
    }
  }
  class OnOffL implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      runFlag = !runFlag;
    }
  }
  public static void main(String[] args) {
    Counter3 applet = new Counter3();
    Frame aFrame = new Frame("Counter3");
    aFrame.addWindowListener(
      new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
          System.exit(0);
        }
      });
    aFrame.add(applet, BorderLayout.CENTER);
    aFrame.setSize(300,200);
    applet.init();
    applet.start();
    aFrame.setVisible(true);
  }
} ///:~

現在run()位於類內,但它在init()結束以後仍處在“睡眠”狀態。若按下啟動按鈕,線程便會用多少有些暧昧的表達方式創建(若線程尚不存在):
new Thread(Counter3.this);
若某樣東西有一個Runnable接口,實際只是意味著它有一個run()方法,但不存在與之相關的任何特殊東西——它不具有任何天生的線程處理能力,這與那些從Thread繼承的類是不同的。所以為了從一個Runnable對象產生線程,必須單獨創建一個線程,並為其傳遞Runnable對象;可為其使用一個特殊的構建器,並令其采用一個Runnable作為自己的參數使用。隨後便可為那個線程調用start(),如下所示:
selfThread.start();
它的作用是執行常規初始化操作,然後調用run()。
Runnable接口最大的一個優點是所有東西都從屬於相同的類。若需訪問什麼東西,只需簡單地訪問它即可,不需要涉及一個獨立的對象。但為這種便利也是要付出代價的——只可為那個特定的對象運行單獨一個線程(盡管可創建那種類型的多個對象,或者在不同的類裡創建其他對象)。
注意Runnable接口本身並不是造成這一限制的罪魁禍首。它是由於Runnable與我們的主類合並造成的,因為每個應用只能主類的一個對象。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved