我正在创建一个 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);
含义:只要告诉“最后一个”关闭,您只需创建一个新实例,而不是将执行程序保留为空。因此,理论上,每当执行器习惯于提交任务或它被关闭时,您正在与当前“有效”的实例交谈。
添加回答
举报
0/150
提交
取消