如何安全地停止我的"类实现Runnable"?

时间:2015-12-02 21:08:47

标签: java multithreading class runnable

Oracle Java SE Docs建议这样做:

您可以通过替换applet的stop并运行方法来避免使用Thread.stop:

private volatile Thread blinker;

public void stop() {
    blinker = null;
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (blinker == thisThread) {
        try {
            Thread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

有没有办法为class blinker implements Runnable执行相同的操作?

由于您必须使用blinker thisClass = this;或类似内容,(blinker == thisClass)是否始终评估为真?

或者这段代码是否足够:

class blinker implements Runnable {
    boolean stop = false;

    @override
    public void run() {

        while (!Thread.currentThread().isInterrupted()) {

            // code
            // ...

            if (stop) { Thread.currentThread().interrupt(); }

            // ...

        }
    }
}

1 个答案:

答案 0 :(得分:0)

可以做类似的事情:

class Blinker implements Runnable {
    Runnable blinker = this;

    public void stop() {
        blinker = null;
    }

    public void run() {
        while(blinker == this) {

        }
    }
}

但这将是毫无意义的。 我认为您并未理解文档试图传达的重点,这是不使用无限循环来保持线程活跃,使用Thread#stop()终止他们。相反,使用条件,然后在想要结束保持线程活动的循环时将其设置为false。

您无需经常检查Thread#isInterrupted()以保持线程活跃。

while(!stop) {

}

会做得很好。您也不应该从线程中断线程。中断的目的是结束停止线程的任务。这些任务位于try/catch内,可以捕获InterruptedException。其他线程通常是负责中断的线程。

文档指的是允许线程正常死亡。

在第一个示例中,run()方法是通过无限循环处理的:while(true)。停止线程的唯一方法是强制某种停止,例如usong Thread#stop

public void run() {
    while (true) {
        try {
            Thread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

但不建议使用Thread#stop。相反,循环应取决于boolean,另一个线程(或当前线程)可以设置为truefalse

private volatile boolean running;

public void stop() {
    running = false;
}

public void run() {
    while (running) {
        try {
            Thread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}

他们使用running而不是使用blinker == thisThread布尔值,然后在他们想要结束循环时更改blinker的值:

private volatile Thread blinker;

public void stop() {
    blinker = null;
}

public void run() {
    Thread thisThread = Thread.currentThread();
    while (blinker == thisThread) {
        try {
            Thread.sleep(interval);
        } catch (InterruptedException e){
        }
        repaint();
    }
}