现在考虑一下创建多个不同的线程的问题。我们不可用前面的例子来做到这一点,所以必须倒退回去,利用从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)的描述内容中:
【责编:admin】