如何使用 ExecutorService 重新启动之前在 Swing 应用程序中终止的线程

我正在创建一个 Swing 应用程序。它包含一个 JFrame,在 JFrame 内部,我添加了一个 JButton 来启动和停止一些任务。我正在使用相同的 JButton 来启动和停止作为线程并由 ExecutorService 执行的任务。


单击开始按钮时,将执行线程并且按钮标签将更改为停止,而单击停止按钮将停止所有线程(我已使用 ExecutorService shutdownNow() 方法完成此操作)并且按钮标签将再次出现更改为开始,但应用程序不会关闭。现在,如果我再次单击“开始”按钮,应用程序将被挂起,线程不会从头开始重新启动。


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);

    }

}


预期:第二次单击“开始”按钮时,应从头开始重新启动所有线程。


有只小跳蛙
浏览 98回答 1
1回答

叮当猫咪

这里: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;换句话说:你开着你的车,你把它点燃,然后你买了一辆新的,再开一辆,然后再把它点燃。当然,设置为 null 并检查它的方法可能会导致各种问题。这样做会更好一些:  executor.shutdownNow();   executor = Executors.newFixedThreadPool(4);含义:只要告诉“最后一个”关闭,您只需创建一个新实例,而不是将执行程序保留为空。因此,理论上,每当执行器习惯于提交任务或它被关闭时,您正在与当前“有效”的实例交谈。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java