Как перезапустить потоки, используя ExecutorService, которые были прерваны ранее в приложении Swing - PullRequest
1 голос
/ 07 мая 2019

Я создаю приложение Swing.Он содержит JFrame, внутри JFrame я добавил JButton для запуска и остановки некоторых задач.Я использую тот же JButton для запуска и остановки задач, которые являются потоками и выполняются ExecutorService.

При нажатии на кнопку «Пуск» будут выполняться потоки, а метка кнопки изменится на «Стоп», а при нажатиикнопка Стоп остановит все потоки (я сделал это с помощью метода shutdownNow () ExecutorService), и метка кнопки будет снова изменена на Пуск, но приложение не будет закрыто.Теперь, если я снова нажму кнопку «Пуск», приложение зависнет, потоки не будут перезапущены с самого начала.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

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

public class MultipleThreads {
    public static ExecutorService executor = Executors.newFixedThreadPool(4);

    public static void main(String[] args) {
        JFrame frame = new JFrame("Stop Thread");
        frame.setSize(200,200);
        frame.setLocationRelativeTo(null);
        frame.setLayout(null);
        JPanel panel = new JPanel();
        panel.setBounds(5,5,150,150);
        panel.setLayout(null);
        JButton btn = new JButton("Start");
        btn.setBounds(10,10,80,25);

        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                if (btn.getText().equals("Start")) {
                    btn.setText("Stop");
                    MultipleThreads2 runThreads = new MultipleThreads2();
                    runThreads.runThreadMethod();
                } else if (btn.getText().equals("Stop")) {
                    try {
                        if (!executor.awaitTermination(800, TimeUnit.MILLISECONDS)) {
                            executor.shutdownNow();
                        } 
                    } catch (InterruptedException e) {
                        executor.shutdownNow();
                    }

                    btn.setText("Start");
                }
            }
        });
        panel.add(btn);
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

class MultipleThreads2 {
    public volatile boolean flag = true;

    public void stopRunning() {
        flag = false;
    }

    public MultipleThreads2() {
        while (flag) {
            try {
                MultipleThreads.executor.submit(t1);
                MultipleThreads.executor.submit(t2);
                flag = false;
                System.out.println(t1.isAlive());
            } catch (Exception e) {

            }
        }
    }

    public void runThreadMethod() {
        flag = true;
        while (flag) {
            try {
                MultipleThreads.executor.submit(t3);
                MultipleThreads.executor.submit(t4);
                    flag = false;
            } catch (Exception e) {

            }
        }
    }

    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println("From t1 Thread");
                    Thread.sleep(1000);
                }
            } catch (Exception e) {

            }
        }
    });

    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println("From t2 Thread");
                    Thread.sleep(500);
                }
            } catch (Exception e) {

            }
        }
    });

    Thread t3 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println("From t3 Thread");
                    Thread.sleep(500);
                }
            } catch (Exception e) {

            }
        }
    });

    Thread t4 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println("From t4 Thread");
                    Thread.sleep(500);
                }
            } catch (Exception e) {

            }
        }
    });
}

Ожидается: при повторном нажатии на кнопку «Пуск» следует перезапустить все потоки с начала..

1 Ответ

1 голос
/ 07 мая 2019

Здесь:

public static ExecutorService executor = Executors.newFixedThreadPool(4);

Вы создаете этот пул потоков один раз. Позже вы звоните

executor.shutdownNow();

Другими словами: вы заводите свою машину, и в какой-то момент вы останавливаете машину, выходите из машины и поджигаете ее. Тогда вы спрашиваете себя: «Хорошо, как я могу использовать эту машину, чтобы ехать домой?». Ну, ты не можешь. Вы просто подожгли его.

То же самое и здесь: когда вы выключаете службу, она исчезает .

Короче говоря, простое (не обязательно идеальное) решение было бы сделать:

public static ExecutorService executor = null;

и позже:

if (executor == null) 
  executor = Executors.newFixedThreadPool(4);

и

executor.shutdownNow();
executor = null;

Другими словами: вы едете на своей машине, поджигаете ее, а затем покупаете новую, чтобы совершить другую, прежде чем поджечь ее.

Конечно, такой подход установки нуля и проверки на это может привести к различным проблемам. Было бы немного лучше сделать:

  executor.shutdownNow();
  executor = Executors.newFixedThreadPool(4);

Значение: вместо того, чтобы оставлять исполнителя равным нулю, вы просто создаете новый экземпляр, как только «последнему» было приказано завершить работу. Таким образом, теоретически, всякий раз, когда исполнитель привыкает выполнять задачи ИЛИ отключается, вы говорите с «действительным» в данный момент экземпляром.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...