Java—停止程序后再次启动程序,而不关闭程序

Java—停止程序后再次启动程序,而不关闭程序,java,exception,exception-handling,Java,Exception,Exception Handling,我有一个Java程序,用来显示通过网络发送给用户的流量信息。目前,用户必须单击“开始”按钮开始接收和查看该信息,然后单击“停止”按钮停止接收该信息 但是,由于我的代码目前的状态,它只会在用户第一次单击“开始”按钮时起作用。。。单击“停止”后,如果再次尝试单击“启动”,将显示控制台错误,显示: 线程“AWT-EventQueue-0”java.util.concurrent.RejectedExecutionException中出现异常:任务。。。已从java.util.concurrent.Th

我有一个Java程序,用来显示通过网络发送给用户的流量信息。目前,用户必须单击“开始”按钮开始接收和查看该信息,然后单击“停止”按钮停止接收该信息

但是,由于我的代码目前的状态,它只会在用户第一次单击“开始”按钮时起作用。。。单击“停止”后,如果再次尝试单击“启动”,将显示控制台错误,显示:

线程“AWT-EventQueue-0”java.util.concurrent.RejectedExecutionException中出现异常:任务。。。已从java.util.concurrent.ThreadPoolExecutor中拒绝。。。终止,池大小=0,活动线程=0,已完成任务=1]

显示网络流量信息的代码处于while循环中,它只是不断循环。在while循环结束时,我有以下代码,用于退出循环/停止捕获:

Boolean queryStopCapture = stopCapture;
if(queryStopCapture == true){
    System.out.println("Break clause in 'queryStopCapture' if statement has been called. ");
    break;
queryStopCapture
的值设置为等于
stopCapture
的值,默认情况下为
false
,但当
ActionListener
听到GUI中单击“停止”按钮时,会更改为
true

有人能给我解释一下这个异常意味着什么,为什么我在尝试重新启动捕获时会遇到它,以及我在尝试重新启动捕获时如何“适应”它吗

用try/catch块单击“开始捕获”按钮的代码是否有效

编辑2014年4月30日11:50

这是我用来“接收”通过网络发送的流量的完整类:

import java.io.Console;
import java.net.*;
import java.util.ArrayList;
import java.applet.*;
import java.awt.*;

import edu.nps.moves.disutil.*;
import edu.nps.moves.dis.*;

/*Receives PDUs from the network in IEEE format. */

public class EspduReceiver {

/*Max size of a PDU in binary format that can be received. Outdated- PDUs can be larger- but this is a reasonable starting point */
public static final int MAX_PDU_SIZE = 8192;

/*Retrieve PDU data for use by class methods */
static MulticastSocket socket;
static DatagramPacket packet;
static InetAddress address;
static PduFactory pduFactory = new PduFactory();

/*Every PDU received by the application will be dynamically added to this ArrayList- so I should be able to access each PDU
 * from anywhere, using each element of the ArrayList. */
public static ArrayList<Pdu> espdu = new ArrayList<Pdu>(); /*Currently, this ArrayList is storing the actual DIS messages- which aren't really 
                                                            human readable */
public static ArrayList<Integer> entitySite = new ArrayList<Integer>();
public static ArrayList<Integer> entityApplication = new ArrayList<Integer>();
public static ArrayList<Integer> entity = new ArrayList<Integer>();

//public static Pdu pdu = pduFactory.createPdu(packet.getData());
//public static EntityID eid = ((EntityStatePdu)pdu).getEntityID();
//public static Vector3Double position = ((EntityStatePdu)pdu).getEntityLocation();

public static void receivePdu(){

    //while(true){

        try{
            /*Specify the socket to receive the data */
            socket = new MulticastSocket(EspduSender.PORT);
            address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
            socket.joinGroup(address); 

            /*Loop infinitely, receiving datagrams */
            while(true){
                byte buffer[] = new byte[MAX_PDU_SIZE];
                packet = new DatagramPacket(buffer, buffer.length);

                socket.receive(packet);

                Pdu pdu = pduFactory.createPdu(packet.getData()); /*Moved this line to the top of the class to declare as global variable (29/04/2014) */

                if(pdu != null){
                    System.out.print("Got PDU of type: " + pdu.getClass().getName());
                    if(pdu instanceof EntityStatePdu){
                        EntityID eid = ((EntityStatePdu)pdu).getEntityID(); /*Moved this line to the top of class to declare as global variable (29/04/2014) */
                        Vector3Double position = ((EntityStatePdu)pdu).getEntityLocation(); /*Moved this line to the top of class to declare as global variable (29/04/2014) */
                        System.out.println(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
                        System.out.println("Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "] ");
                        /*Add PDU to ArrayList of PDUs */
                        espdu.add(pdu);
        /*              System.out.println(" PDU added to arrayList. "); 
                        System.out.println(espdu); /*This is printing out the actual DIS messages (i.e. edu.nps.moves.dis.EntityState...),
                        maybe try adding the 'eid.getSite()', etc to an ArrayList instead. Use Associative arrays/ map/ hashmap */

                        entitySite.add(eid.getSite());
                        System.out.println("Entity Site added to ArrayList. ");
                        entityApplication.add(eid.getApplication());
                        System.out.println("Entity Application added to ArrayLIst. ");
                        entity.add(eid.getEntity());
                        System.out.println("Entity ID added to ArrayList");

                        /*Check that everything is actually in the ArrayLists 
                        for(int i : entity){ /*Substituted 'entity' with 'entitySite' and 'entityApplication'- values are all printed correctly. 
                        System.out.println(i);
                        } */

                        /*Now append each PDU to the text area */
                        Gui.displayOutput.append("\n");
                        Gui.displayOutput.append("EID: [" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "]. ");
                        Gui.displayOutput.append("Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "] ");

                    } else if(!(pdu instanceof EntityStatePdu)){
                        System.out.println("There are no PDUs currently being received.");
                    }
                    System.out.println();
                }
                Thread.sleep(1000);
                /*Try adding a boolean to allow me to stop the capture by clicking 'stop' button- Look on stackoverflow */
                boolean queryStopCapture =  stopCapture;
                if(queryStopCapture ==  true){
                    System.out.println("Break clause in 'queryStopCapture' if statement has been called. ");
                    break;
                } 
            } /*end while */
        } /*end try */
        catch(Exception e){
            System.out.println(e);
            e.printStackTrace();
            System.out.println("This is where the error is being generated");
            /*09/04/2014 @ 17:100
             * If this exception gets called, presumably it either means that pdu is not an instance of EntityStatePdu, or
             * that pdu does not actually hold a packet.  */
        }
        /*Try adding a boolean to allow me to stop the capture by clicking 'stop' button- Look on stackoverflow */
    /*  boolean queryStopCapture =  stopCapture;
        if(queryStopCapture ==  true){
            break;
        } */
    //}
}

public static boolean stopCapture = false;

public static void main(String args[]){

    receivePdu();
/*  MulticastSocket socket;
    DatagramPacket packet;
    InetAddress address;
    PduFactory pduFactory = new PduFactory();

    try{
        /*Specify the socket to receive the data 
        socket = new MulticastSocket(EspduSender.PORT);
        address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
        socket.joinGroup(address); 

        /*Loop infinitely, receiving datagrams 
        while(true){
            byte buffer[] = new byte[MAX_PDU_SIZE];
            packet = new DatagramPacket(buffer, buffer.length);

            socket.receive(packet);

            Pdu pdu = pduFactory.createPdu(packet.getData()); /*    Commented on 15/04/2014 @ 09:15 

            if(pdu != null){
                System.out.print("Got PDU of type: " + pdu.getClass().getName());
                if(pdu instanceof EntityStatePdu){
                    EntityID eid = ((EntityStatePdu)pdu).getEntityID();
                    Vector3Double position = ((EntityStatePdu)pdu).getEntityLocation();
                    System.out.print(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
                    System.out.print(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]");
                } else if(!(pdu instanceof EntityStatePdu)){
                    System.out.println("There are no PDUs currently being received.");
                }
                System.out.println();
            }
        } /*end while 
    } /*end try 
    catch(Exception e){
        System.out.println(e);
        e.printStackTrace();
        System.out.println("This is where the error is being generated");
        /*09/04/2014 @ 17:100
         * If this exception gets called, presumably it either means that pdu is not an instance of EntityStatePdu, or
         * that pdu does not actually hold a packet.  
    } */
} /*end main */

/*Create an 'Inner Class' (use as a C struct) to hold all of the variables pertaining to each PDU- each instance of the class
 * will hold a separate PDU. 
 * Create a method in Gui.java that will retrieve each instance of the inner class, and display the values on screen.*/

public class PDU{

    public String entityID;
    public double xLocation;
    public double yLocation;
    public double zLocation;
}



} /*end class */
导入java.io.Console;
导入java.net。*;
导入java.util.ArrayList;
导入java.applet.*;
导入java.awt.*;
导入edu.nps.moves.disutil.*;
导入edu.nps.moves.dis.*;
/*以IEEE格式从网络接收PDU*/
公共级EspduReceiver{
/*可以接收的二进制格式PDU的最大大小。过时的PDU可以更大,但这是一个合理的起点*/
公共静态最终int MAX_PDU_SIZE=8192;
/*检索PDU数据以供类方法使用*/
静态多播插座;
静态数据包;
静态地址;
静态PduFactory PduFactory=新PduFactory();
/*应用程序接收到的每个PDU都将动态添加到此ArrayList中,因此我应该能够访问每个PDU
*从任意位置,使用ArrayList的每个元素*/
public static ArrayList espdu=new ArrayList();/*当前,此ArrayList正在存储实际的DIS消息,但实际上并不是
可读*/
public static ArrayList entitySite=new ArrayList();
公共静态ArrayList entityApplication=new ArrayList();
公共静态ArrayList实体=新ArrayList();
//public static Pdu Pdu=pduFactory.createPdu(packet.getData());
//公共静态EntityID eid=((EntityStatePdu)pdu).getEntityID();
//公共静态向量3双位置=((EntityStatePdu)pdu.getEntityLocation();
公共静态无效接收PDU(){
//while(true){
试一试{
/*指定要接收数据的套接字*/
套接字=新的多播套接字(EspduSender.PORT);
address=InetAddress.getByName(EspduSender.DEFAULT\u多播组);
socket.joinGroup(地址);
/*无限循环,接收数据报*/
while(true){
字节缓冲区[]=新字节[最大PDU大小];
数据包=新数据包(buffer,buffer.length);
套接字接收(数据包);
Pdu Pdu=pduFactory.createPdu(packet.getData());/*将此行移到类的顶部以声明为全局变量(2014年4月29日)*/
如果(pdu!=null){
System.out.print(“获取类型为:”+PDU.getClass().getName())的PDU);
if(实体状态pdu的pdu实例){
EntityID eid=((EntityStatePdu)pdu).getEntityID();/*将此行移到类的顶部以声明为全局变量(2014年4月29日)*/
Vector3Double position=((EntityStatePdu)pdu).getEntityLocation();/*将此行移动到类的顶部,以声明为全局变量(2014年4月29日)*/
System.out.println(“EID:[“+EID.getSite()+”,“+EID.getApplication()+”,“+EID.getEntity()+”);
System.out.println(“DIS坐标中的位置:[“+position.getX()+”,“+position.getY()+”,“+position.getZ()+”]);
/*将PDU添加到PDU的ArrayList*/
espdu.add(pdu);
/*System.out.println(“添加到arrayList的PDU”);
System.out.println(espdu);/*这是打印实际DIS消息(即edu.nps.moves.DIS.EntityState…),
可以尝试将“eid.getSite()”等添加到ArrayList中。请使用关联数组/map/hashmap*/
添加(eid.getSite());
System.out.println(“添加到ArrayList的实体站点”);
entityApplication.add(eid.getApplication());
System.out.println(“添加到ArrayLIst的实体应用程序”);
entity.add(eid.getEntity());
System.out.println(“添加到ArrayList的实体ID”);
/*检查所有内容是否都在ArrayList中
对于(inti:entity){/*用“entitySite”和“entityApplication”替换的“entity”-值都正确打印。
系统输出打印LN(i);
} */
/*现在将每个PDU附加到文本区域*/
Gui.displayOutput.append(“\n”);
Gui.displayOut
import java.applet.*;
import java.awt.*;

import javax.swing.*;

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

public class Gui extends JFrame{

public static String text = "";
public static int rows = 20;
public static int columns = 5;
public static JTextArea displayOutput = new JTextArea(text, rows, columns);

/*Create a JComboBox to display filter options, and JTextField to allow user to enter filter criteria */
public static String[] filterOptions = {"", "Site", "Application", "ID"};
public static JComboBox<String> filter1 = new JComboBox<String>(filterOptions); /*Adding the '<String>' parameters to JComboBox got rid of the warnings 29/04/2014 */
public static JTextField filter1Text = new JTextField();
public static JComboBox filter2 = new JComboBox(filterOptions);
public static JTextField filter2Text = new JTextField();
public static JComboBox filter3 = new JComboBox(filterOptions);
public static JTextField filter3Text = new JTextField();

public Gui(){
    setTitle("DIS Filter");
    setSize(1000, 500);
    setLocation (10, 10);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    initGui();
}

/*public quitButton(){
    initGui();
} */

private void initGui(){
    //JFrame frame = new JFrame();
    JPanel panel = new JPanel();

    this.getContentPane().add(panel);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setTitle("DIS Filter");
    this.setSize(1200, 600);

    panel.setLayout(null);
    /*Add a JTextArea to display the output DIS information */
    //JTextArea displayOutput = new JTextArea(text, rows, columns);
    displayOutput.setBounds(10, 10, 700, 500);
    panel.add(displayOutput);
    displayOutput.setEditable(false);
    //displayOutput.setEditable(false);
    add(panel);
    //displayOutput.append("hello");


    //String data = EspduReceiver.espdu;
//  EspduReceiver.receivePdu(); /*The code underneath here will never be reached unless I specify how long to perform this method call for- */
                                /*Since the receivePdu() method has no 'end' condition- it keeps looping continually until told to stop */
                                /*Try using a timer to specify how long it should be called for */
    long start = System.currentTimeMillis();
    long end = start + 60*1000; /* 60 seconds * 1000 ms/sec */
/*  while (System.currentTimeMillis() < end){

        int n = EspduReceiver.entitySite.size(); /*This is what to use, but set n to 10 for testing purposes. 
        //int n = 10;
        System.out.print(n);
        for (int i = 0; i < n; i++){
//          EspduReceiver.receivePdu();
            System.out.print("Entered 'for' loop. ");
            System.out.println(EspduReceiver.entitySite.get(i));
            System.out.println(EspduReceiver.entityApplication.get(i));
            System.out.println(EspduReceiver.entity.get(i));
            displayOutput.append(EspduReceiver.entitySite.get(i).toString());
            displayOutput.append(EspduReceiver.entityApplication.get(i).toString());
            displayOutput.append(EspduReceiver.entity.get(i).toString());
        }       
    } */ /*Maybe need to move this while loop into another class/ add the code to the method that I will call to display output */



    /*Create an ExecutorService and then call shutdown in my ActionListener for stop */
    final ExecutorService pool = Executors.newSingleThreadExecutor();

    /*Create 'Quit' button and add it to the panel */
    JButton quitButton = new JButton("Quit");
    panel.add(quitButton);
    quitButton.setBounds(1080, 500, 80, 30); /*Set the location of the button in the window, and its size */

    quitButton.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e){
            System.exit(0);
            pool.shutdown();
        }
    });

    //panel.add(quitButton);
    //setTitle("Quit");
    //setSize(60,30); /*This line was overwriting the previously set values for the size of the window */
    setLocationRelativeTo(null);
    panel.repaint();
    setDefaultCloseOperation(EXIT_ON_CLOSE);    


    /*Create 'StartCapture' button and add it to the panel */
    JButton startCaptureButton = new JButton("Start");
    panel.add(startCaptureButton);
    startCaptureButton.setBounds(1080, 350, 80, 30);

    startCaptureButton.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e){
            /*Try adding ExecutorService code here */
            pool.execute(new Runnable(){
                public void run(){
                    /*For some reason, the call to EspduReceiver.receivePdu(); doesn't work if the capture has already been stopped once.
                     * Tried surrounding it with a try/catch block, but this didn't make a difference */
                    try{
                        EspduReceiver.receivePdu();
                    } catch(Exception e){
                        System.out.println("Cannot start capture again after stopping");
                    }
                }
            });
            /*Add method call to receivePdu(); here */
            //EspduReceiver.receivePdu();
        }
    });


    /*Create 'StopCapture' button and add it to the panel */
    JButton stopCaptureButton = new JButton("Stop");
    panel.add(stopCaptureButton);
    stopCaptureButton.setBounds(1080, 400, 80, 30);

    stopCaptureButton.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e){
            EspduReceiver.stopCapture = true;
            pool.shutdown();
        }
    });

    /*Add the filters to the window */
    panel.add(filter1);
    filter1.setBounds(720, 50, 100, 30);
    panel.add(filter1Text);
    filter1Text.setBounds(850, 50, 200, 30);

    panel.add(filter2);
    filter2.setBounds(720, 90, 100, 30);
    panel.add(filter2Text);
    filter2Text.setBounds(850, 90, 200, 30);

    panel.add(filter3);
    filter3.setBounds(720, 130, 100, 30);
    panel.add(filter3Text);
    filter3Text.setBounds(850, 130, 200, 30);


    /*Add buttons that will call 'retrieve' functions from Filter.java, and display only the entities that match the filtered
     *  values in the GUI. */

    /*Get entities with matching site */
    JButton getSiteEntitiesButton = new JButton("Get Site entities");
    panel.add (getSiteEntitiesButton);
    getSiteEntitiesButton.setBounds(900, 400, 80, 30);

    getSiteEntitiesButton.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e){
            /*Need to check if there are any PDUs stored in 'entity' arrays first- if there aren't, then add a call to receivePdu() at
             *  the start of this method; if there are, then get the value entered into the text box, and search through the array for 
             *  a matching value.  */
            try{
            if(EspduReceiver.entitySite.get(0) == null){
                EspduReceiver.receivePdu();
                Filter.retrieveFilteredSite();
            } else {
            /*Need to add code to retrieve value of 'filter1Text */
            Filter.retrieveFilteredSite();
            }

            }catch(Exception ex){
                System.out.println("No PDUs have yet been received. You must receive at least one PDU before you can search for a matching site entity. ");
            }
        }
    });

}

public static void main(String[] args){ /* I probably don't need a main method here- I have one in EspduReceiver.java */
    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run(){
            Gui gui = new Gui();
            gui.setVisible(true);
        }
    });
}




}
 JButton stopCaptureButton = new JButton("Stop");
    panel.add(stopCaptureButton);
    stopCaptureButton.setBounds(1080, 400, 80, 30);

    stopCaptureButton.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e){
            EspduReceiver.stopCapture = true;
            pool.shutdown();
        }
    });
startCaptureButton.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e){
            /*Try adding ExecutorService code here */
EspduReceiver.stopCapture = false;
            pool.execute(new Runnable(){
                public void run(){
                    /*For some reason, the call to EspduReceiver.receivePdu(); doesn't work if the capture has already been stopped once.
                     * Tried surrounding it with a try/catch block, but this didn't make a difference */
                    try{
                        EspduReceiver.receivePdu();
                    } catch(Exception e){
                        System.out.println("Cannot start capture again after stopping");
                    }
                }
            });