如何停止一个线程?

3
我制作了一个倒计时器,"停止"按钮应该停止倒计时并重置文本框。
class Count implements Runnable {
    private Boolean timeToQuit=false;

    public void run() {
        while(!timeToQuit) {
            int h = Integer.parseInt(tHrs.getText());
            int m = Integer.parseInt(tMins.getText());
            int s = Integer.parseInt(tSec.getText());
            while( s>=0 ) {
                try {
                    Thread.sleep(1000);
                }
                catch(InterruptedException ie){}
                if(s == 0) {
                    m--;
                    s=60;
                    if(m == -1) {
                        h--;
                        m=59;
                        tHrs.setText(Integer.toString(h));
                    }
                    tMins.setText(Integer.toString(m));
                }
                s--;
                tSec.setText(Integer.toString(s));
            }
        }
        tHrs.setText("0");
        tMins.setText("0");
        tSec.setText("0");
    }

    public void stopRunning() {
        timeToQuit = true;
    }
}

当“停止”按钮被按下时,我调用stopRunning() ,但它不起作用。

另外,我是否正确地调用了stopRunning()

public void actionPerformed(ActionEvent ae) 
{
    Count cnt = new Count();
    Thread t1 = new Thread(cnt);
    Object source = ae.getSource();
    if (source == bStart)
    {
        t1.start();
    }
    else if (source == bStop)
    {
        cnt.stopRunning();
    }
}
1个回答

5

您需要将timeToQuit变量设置为volatile,否则false的值将被缓存。此外,没有理由将其设置为Boolean——原始类型也可以使用:

private volatile boolean timeToQuit=false;

您还需要更改内部循环的条件以注意 timeToQuit

while( s>=0 && !timeToQuit) {
    ...
}

你也可以添加对interrupt的调用,但是由于你的线程从未超过一秒钟来检查标志,因此这并不是必要的。


@RahulTripathi 是的,一个人可以这样做,但由于 OP 的代码每秒钟检查一次标志,所以这一切能为您节省的只是不到一秒的延迟。 - Sergey Kalinichenko
@RahulTripathi 知道线程必须每秒检查一次标志,我可能不会添加对 interrupt() 的调用。如果轮询间隔超过两秒钟,我会添加对 interrupt() 的调用。我的经验法则是:终端用户可以容忍不到一秒的延迟而不抱怨;超过一两秒的任何延迟都会让他们感到焦虑,而五秒钟的延迟会让他们点击重新加载按钮;-) - Sergey Kalinichenko
当我点击了停止按钮后,出现了“已停止”信息……所以我猜调用方式应该没问题了吧? - stringbacon
@stringbacon 哦,我看到另一个问题了 - 看一下更新。 - Sergey Kalinichenko
@stringbacon 这是因为每次用户点击按钮时,您都会创建一个新的 Count 实例。创建一个 Count 的单一实例,并在每次通过点击方法使用它。这里有一个修复方案在 pastebin 上:链接 - Sergey Kalinichenko
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接