为什么我的秒表程序无法运行?

时间:2019-07-18 19:05:41

标签: java

我正在尝试通过设计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);
            }
        }
    }
}

期望的输出是秒表。 但是我的秒表没有响应按钮。

1 个答案:

答案 0 :(得分:0)

尝试将volatile关键字添加到变量changed中,

volatile boolean changed;

有时,变量被缓存在线程中,而在另一个线程对其进行更改时不会更新。 此关键字会在每次读取时强制更新值。