同时中断多个线程

时间:2019-01-04 20:09:22

标签: java multithreading thread-safety interrupted-exception

我在一个框架上有3个线程,当我按下“退出”按钮时,我要o停止当前正在运行的线程,然后用程序关闭该框架。为此,我创建了一个数组,其中包含框架的所有线程,并且当按下“退出”按钮时,程序将遍历该数组,如果有正在运行的线程,我将中断它。我的方法的问题是该程序仅停止1个线程,而不是所有线程。因此,即使框架是封闭的,后台也会有2个线程在运行。

这是我的程序:

   import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.Thread.State;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ProgramInterface extends JFrame {

    private JButton stopThreadsAndExit;

    private CounterThread[] counterThreadsArray = new CounterThread[3];

    public static void main(String[] args) {
        new ProgramInterface();
    }

    public ProgramInterface() {
        // TODO Auto-generated constructor stub
        addCounterThreadsToArray();
        addThreadsOnTheFrame();
        stopThreadsAndExit = new JButton("Exit");
        addActionToExitButton();
        add(stopThreadsAndExit);
        setFrameSettings();

    }

    private void setFrameSettings() {
        setSize(400, 400);
        setLayout(new FlowLayout());
        setVisible(true);
    }

    public void addThreadsOnTheFrame() {
        for (CounterThread counter : counterThreadsArray) {
            add(counter);
        }
    }

    public void addActionToExitButton() {
        stopThreadsAndExit = new JButton("Exit");

        stopThreadsAndExit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        exit();
                    }
                }).start();

            }
        });

    }

    public void exit() {
        for (CounterThread counter : counterThreadsArray) {
            if (counter.isRunnable()) {
                counter.interruptThread();
            }
        }
        dispose();
    }

    private void addCounterThreadsToArray() {
        counterThreadsArray[0] = new CounterThread("Thread 01");
        counterThreadsArray[1] = new CounterThread("Thread 02");
        counterThreadsArray[2] = new CounterThread("Thread 03");
    }
}

class CounterThread extends JPanel {

    Thread counter;

    private String threadName;
    private JButton startThread;

    public CounterThread(String threadString) {
        this.threadName = threadString;
        initializesCounterThread();
        addActionToStartButton();
        setLayout(new FlowLayout());
        add(startThread);
    }

    public void addActionToStartButton() {
        startThread = new JButton("Start " + threadName);
        startThread.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                counter.start();
            }
        });

    }

    private void initializesCounterThread() {
        counter = new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    for (int i = 0; i < 1000000000; i++) {
                        if (Thread.currentThread().isInterrupted()) {
                            throw new InterruptedException();
                        }
                        System.out.println(threadName + " generated " + i);
                    }
                } catch (InterruptedException e) {
                    // TODO: handle exception
                    Thread.currentThread().interrupt();
                }
            }

        });
    }

    public void interruptThread() {
        counter.interrupt();
    }

    public boolean isRunnable() {
        return counter.getState() == State.RUNNABLE;
    }
}

1 个答案:

答案 0 :(得分:2)

不要在线程上检查getState,您不必关心它是否正在运行。只需在上面调用中断即可。

在仅在该实例上设置标志的线程上调用中断时。当线程执行某些操作(例如等待或睡眠)或线程显式调用isInterrupted(正在执行)时,将检查该标志。因此,您无需关心线程处于什么状态。