我正在尝试通过设计GUI秒表来将我在多线程中学到的东西付诸实践。
我正在使用Eclipse。我也尝试调试。在调试模式下,当我传递语句以更改文本字段的文本时,它不会更改输出窗口中的实际文本。
更奇怪的是,在所有这些情况下,我的月食崩溃了,输出窗口打开了。然后程序开始运行。
这是主要类,分别通过对象I和T初始化两个线程的前台,后台。
public class Coordinator {
public static void main(String[] args) {
Interface I = new Interface();
Thread fore = new Thread(I,"foreground");
timer T = new timer(I);
Thread back = new Thread(T, "background");
fore.start();
back.start();
}
}
这是一个线程类,只要将布尔变量“ changed”设置为true,它就会不断更新屏幕上的文本。一旦更新了文本,它将再次将'changed'的值设置为false。 它还管理GUI。 GUI借助开始,停止和重置按钮来更改布尔变量“正在运行”的值。
public class Interface extends JFrame implements ActionListener, Runnable {
JButton start,stop,reset;
JTextField time;
Container pane;
String Reading;
boolean Running,changed;
long centisec;
public Interface() {
Reading = "00:00:00:00";
Running = false;
changed = false;
centisec = 0;
pane = getContentPane();
pane.setBackground(Color.WHITE);
pane.setLayout(new FlowLayout());
time = new JTextField(Reading);
start = new JButton("START");
stop = new JButton("STOP");
reset = new JButton("RESET");
start.addActionListener(this);
stop.addActionListener(this);
reset.addActionListener(this);
pane.add(time);
pane.add(start);
pane.add(stop);
pane.add(reset);
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String but = e.getActionCommand();
if (but.equals("START"))
{
Running = true;
}
if (but.equals("STOP"))
{
Running = false;
}
if (but.equals("RESET"))
{
Running = false;
centisec = 0;
changed = true;
}
}
private void updateReading() {
int hour,minute,second,centisecond;
long temp = centisec;
String h,m,s,c;
hour = (int) (temp / (360000));
temp = temp % 360000;
h = (hour>=10)?"":"0";
minute = (int) (temp / 6000);
temp = temp % 6000;
m = (minute>=10)?"":"0";
second = (int) (temp / 100);
temp = temp % 100;
s = (second>=10)?"":"0";
centisecond = (int) temp;
c = (centisecond>=10)?"":"0";
Reading = h+hour+':'+m+minute+':'+s+second+':'+c+centisecond;
}
public boolean isRunning() {
return Running;
}
public void incCentisec() {
centisec++;
}
public void run() {
setSize(2000,1000);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
for(;;)
{
if(changed)
{
updateReading();
time.setText(Reading);
changed = false;
}
}
}
public void setChanged(boolean changed) {
this.changed = changed;
}
}
该线程类以10毫秒的间隔不断更新变量中的时间数据值(仅当“ Running”设置为true时)。之后,它将“ changed”的值更改为true,以便其他线程将该新值更新到屏幕上。
public class timer implements Runnable {
Interface I;
public timer(Interface i) {
super();
I = i;
}
public void run() {
for(;;) {
if (I.isRunning())
{
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I.incCentisec();
I.setChanged(true);
}
}
}
}
期望的输出是秒表。 但是我的秒表没有响应按钮。
答案 0 :(得分:0)
尝试将volatile
关键字添加到变量changed
中,
volatile boolean changed;
有时,变量被缓存在线程中,而在另一个线程对其进行更改时不会更新。 此关键字会在每次读取时强制更新值。