Уничтожение потока в SwingUtilities.invokeLater()

У меня есть качающееся приложение. После нажатия элемента меню в строке меню я пытаюсь выполнить вызов API, который предположительно займет некоторое время.

Я не хотел, чтобы приложение Swing застревало/зависало до тех пор, пока вызов API не даст свой результат, поэтому я использовал SwingUtilities.invokeLater, чтобы отделить вновь созданный поток, который позаботится о вызове API. Ниже приведен код для вышеуказанного

public void actionPerformed(ActionEvent e){
    Object src=e.getSource();

    if(src.equals(theJMenuItemClicked)){
        SwingUtilities.invokeLater(new Runnable() {

                    @Override
                    public void run() {
                        //apicall here
                    }
                })
    }

Пока поток вызовов API работает, я показываю JDIalog с сообщением о том, что «вызов API выполняется», и кнопкой «Прервать поток».

Я хотел бы убить поток, нажав кнопку «ABort Thread» в Jdialog.

Если это обычный поток, у нас есть Thread t = new Thread(new Runnable()), и мы вызываем t.stop для него же.

Как мне получить этот конкретный экземпляр потока, порожденный SwingUtilities, чтобы я мог остановить его? Проще говоря, как я могу убить созданный выше поток?


person Vamsi Emani    schedule 13.05.2011    source источник


Ответы (1)


public class SwingUtilitiesExample implements ActionListener {

// Declaration of Swing Components
private JMenuItem menuItem;
private JButton abortOperation;

// Thread-safe indicator of the presence of the Thread
private volatile boolean isThreadRunning = false;

public SwingUtilitiesExample() {
    // Initialize Swing Components 
    menuItem = new JMenuItem();

    // Add ActionListeners
    menuItem.addActionListener(this);
    abortOperation.addActionListener(this);
}

@Override
public void actionPerformed(ActionEvent e) {
    Object source = e.getSource();
    if (source.equals(menuItem)) {
        isThreadRunning = true;
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                while (isThreadRunning) {
                    // API calls here
                }
            }
        });
    } else if (source.equals(abortOperation)) {
        isThreadRunning = false;
    }
}
}

Изменив значение isThreadRunning на false, вы можете эффективно прервать поток. Пока поток регулярно проверяет это логическое значение, этот код будет работать нормально.

Метод Thread.stop() устарел. Oracle заявляет, что этот метод по своей сути небезопасен. Поэтому следует воздержаться от его использования. Вместо этого попробуйте использовать потокобезопасные логические переменные для управления потоком потока, как показано в приведенном выше примере кода.

Если вы хотите вернуть какой-то тип после того, как закончите работу с потоком, вы можете рассмотреть SwingWorker.

person Oskar    schedule 23.10.2011