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

Java 如何使用先前在Swing应用程序中终止的ExecutorService重新启动线程,java,multithreading,swing,executorservice,Java,Multithreading,Swing,Executorservice,我正在创建一个Swing应用程序。它包含一个JFrame,在JFrame中,我添加了一个JButton来启动和停止一些任务。我使用相同的JButton来启动和停止由ExecutorService执行的线程任务 单击开始按钮时,线程将被执行,按钮标签将更改为停止,而单击停止按钮将停止所有线程(我使用ExecutorService shutdownNow()方法完成了此操作),按钮标签将再次更改为开始,但应用程序将不会关闭。 现在,如果我再次单击开始按钮,应用程序将被挂起,线程不会从头开始重新启动

我正在创建一个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);
    }
}

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

            }
        }
    });
}
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.TimeUnit;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类多线程{
publicstaticexecutorservice executor=Executors.newFixedThreadPool(4);
公共静态void main(字符串[]args){
JFrame=新JFrame(“止动螺纹”);
框架。设置尺寸(200200);
frame.setLocationRelativeTo(空);
frame.setLayout(空);
JPanel面板=新的JPanel();
专家组:立根(5,5150150);
panel.setLayout(空);
JButton btn=新JButton(“开始”);
btn.立根(10,10,80,25);
btn.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效行动(行动事件ae){
if(btn.getText().equals(“Start”)){
btn.setText(“停止”);
MultipleThreads2 runThreads=新的MultipleThreads2();
runThreads.runThreadMethod();
}else if(btn.getText().equals(“Stop”)){
试一试{
如果(!执行器等待终止(800,时间单位毫秒)){
执行者。关机现在();
} 
}捕捉(中断异常e){
执行者。关机现在();
}
btn.setText(“开始”);
}
}
});
面板。添加(btn);
框架。添加(面板);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
类多线程2{
public volatile boolean flag=true;
public void stop running(){
flag=false;
}
公共多线程2(){
while(旗帜){
试一试{
多线程执行器提交(t1);
多线程执行器提交(t2);
flag=false;
System.out.println(t1.isAlive());
}捕获(例外e){
}
}
}
public void runThreadMethod(){
flag=true;
while(旗帜){
试一试{
多线程执行器提交(t3);
多线程执行器提交(t4);
flag=false;
}捕获(例外e){
}
}
}
线程t1=新线程(新的可运行线程(){
@凌驾
公开募捐{
试一试{
对于(int i=0;i<10;i++){
System.out.println(“从t1线程”);
睡眠(1000);
}
}捕获(例外e){
}
}
});
线程t2=新线程(新可运行(){
@凌驾
公开募捐{
试一试{
对于(int i=0;i<10;i++){
System.out.println(“从t2线程”);
睡眠(500);
}
}捕获(例外e){
}
}
});
线程t3=新线程(新可运行(){
@凌驾
公开募捐{
试一试{
对于(int i=0;i<10;i++){
System.out.println(“从t3线程”);
睡眠(500);
}
}捕获(例外e){
}
}
});
线程t4=新线程(新可运行(){
@凌驾
公开募捐{
试一试{
对于(int i=0;i<10;i++){
System.out.println(“从t4线程”);
睡眠(500);
}
}捕获(例外e){
}
}
});
}
预期:当第二次单击开始按钮时,应从头开始重新启动所有线程。

此处:

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

            }
        }
    });
}
public static ExecutorService executor = Executors.newFixedThreadPool(4);
您只创建了一次线程池。稍后,你会打电话来

executor.shutdownNow();
换句话说:你正在启动你的车,在某个时刻,你停下车,下车,然后点燃它。然后你问自己:“好吧,我怎么能用那辆车开车回家?”。嗯,你不能。你只是点燃了它

这里也是一样:当你关闭服务时,它就消失了

长话短说,一个简单(不一定理想)的解决方案是:

public static ExecutorService executor = null;
后来:

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

换言之:你开车,你点燃了你的车,然后你买了一辆新的,在点燃它之前再开一次车

当然,这种设置为null并检查是否为null的方法可能会导致各种问题。这样做会更好一些:

  executor.shutdownNow();
  executor = Executors.newFixedThreadPool(4);
意思是:不要将executor保留为null,只要“最后一个”被告知关闭,就可以创建一个新实例。因此,从理论上讲,每当执行器习惯于提交任务或关闭时,您都在与当前“有效”的实例对话。

无关:永远不要使用空的catch块。至少打印例外情况。你真的很想知道你的代码什么时候会因为某种原因抛出。你是