为什么在Java中停止线程如此困难?

Mat*_*ias 2 java multithreading

我再次出现在其中一种情况下,它不可能停止/销毁/暂停一个线程..interrupt()没有这个技巧,并且不推荐使用.stop()和.suspend().

很简单的例子:

public class TimerThread extends Thread {

    private JPanel colorPanel;

    public TimerThread(JPanel colorPanel) {
        this.colorPanel = colorPanel;
    }

    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
                colorPanel.repaint();
            } catch (Exception ex) {
                //do Nothing
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样做是每秒重新绘制一个JPanel来改变它的颜色.我想从另一个类开始和停止这样的线程:

timer = new Thread(new TimerThread(colorPanel));

    startButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            timer.start();
        }
    });

    stopButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            timer.interrupt();
        }
    });
Run Code Online (Sandbox Code Playgroud)

显然(?)这不起作用...我知道我可以使用Timer,SwingWorker或声明计时器,timer = new TimerThread(colorPanel);并在run方法中使用布尔值而不是"true",但我被要求声明计时器作为"线程",没有别的.

令我惊讶的是(或者这是愚蠢的?),即使这样也行不通:

startButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            timer = new Thread(new TimerThread(colorPanel));
            timer.start();
        }
    });

    stopButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            timer.interrupt();
            timer = null;
        }
    });
Run Code Online (Sandbox Code Playgroud)

所以我的问题很简单:如何在Java中创建线程启动/暂停/恢复/停止?

rat*_*eak 5

当你得到一个中断时,你应该开始清理并尽快返回(或者至少重置中断状态)

while (true) {
    try {
        Thread.sleep(1000);
        colorPanel.repaint();
    } catch(InterruptedException e){//from sleep
        return;//i.e. stop
    } catch (Exception ex) {
        //do Nothing
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是检查Thread.interrupted()条件(但是你需要在InterruptedException的catch中重置中断状态

然而,在挥杆中你可以javax.swing.Timer用来让事件每隔一段时间运行一次,然后用api来阻止它

javax.swing.Timer timer = new Timer(1000,new ActionListener() {
     public void actionPerformed(ActionEvent e) {
         colorPanel.repaint();
     }
});
timer.setRepeats(true);

startButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        timer.start();
    }
});

stopButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        timer.stop();
    }
});
Run Code Online (Sandbox Code Playgroud)