有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么我的秒表程序不能运行?

我试图通过设计一个GUI秒表来实践我在多线程中学到的东西

我正在使用Eclipse。我也试过调试。在调试模式下,当我传递语句以更改textfield的文本时,它不会更改输出窗口中的实际文本

更奇怪的是,我的EclipseIDE有一次崩溃,输出窗口是打开的。然后程序开始运行

这是一个主类,它分别通过对象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时,它就会不断更新屏幕上的文本。更新文本后,它会再次将“更改”的值设置为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) 个答案

  1. # 1 楼答案

    尝试将volatile关键字添加到变量changed,如下所示

    volatile boolean changed;
    

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