为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

有只小跳蛙 2022-11-10 16:23:49
我正在创建一个 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);    }}预期:第二次单击“开始”按钮时,应从头开始重新启动所有线程。
查看完整描述

1 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

这里:

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

含义:只要告诉“最后一个”关闭,您只需创建一个新实例,而不是将执行程序保留为空。因此,理论上,每当执行器习惯于提交任务或它被关闭时,您正在与当前“有效”的实例交谈。


查看完整回答
反对 回复 2022-11-10
  • 1 回答
  • 0 关注
  • 97 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信