現在考慮一下創建多個不同的線程的問題
下面這個例子用計數器和切換按鈕再現了前面的編碼樣式
//: Counter
// If you separate your thread from the main
// class
// want
import java
import java
import java
class Ticker extends Thread {
private Button b = new Button(
private TextField t = new TextField(
private int count =
private boolean runFlag = true;
public Ticker(Container c) {
b
Panel p = new Panel();
p
p
c
}
class ToggleL implements ActionListener {
public void actionPerformed(ActionEvent e) {
runFlag = !runFlag;
}
}
public void run() {
while (true) {
if(runFlag)
t
try {
sleep(
} catch (InterruptedException e){}
}
}
}
public class Counter
private Button start = new Button(
private boolean started = false;
private Ticker[] s;
private boolean isApplet = true;
private int size;
public void init() {
// Get parameter
if(isApplet)
size =
Integer
s = new Ticker[size];
for(int 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不僅包括了自己的線程處理機制,也提供了控制與顯示線程的工具。tW.WIngwIT.CoM可按自己的意願創建任意數量的線程,毋需明確地創建窗口化組件。
在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()會深深地陷入一個無限循環——很難在多任務處理期間中止退出。因此,程序對用戶操作的反應靈敏度會大幅度降低。
From:http://tw.wingwit.com/Article/program/Java/gj/201311/27269.html