Java—停止程序后再次启动程序,而不关闭程序
我有一个Java程序,用来显示通过网络发送给用户的流量信息。目前,用户必须单击“开始”按钮开始接收和查看该信息,然后单击“停止”按钮停止接收该信息 但是,由于我的代码目前的状态,它只会在用户第一次单击“开始”按钮时起作用。。。单击“停止”后,如果再次尝试单击“启动”,将显示控制台错误,显示: 线程“AWT-EventQueue-0”java.util.concurrent.RejectedExecutionException中出现异常:任务。。。已从java.util.concurrent.ThreadPoolExecutor中拒绝。。。终止,池大小=0,活动线程=0,已完成任务=1] 显示网络流量信息的代码处于while循环中,它只是不断循环。在while循环结束时,我有以下代码,用于退出循环/停止捕获:Java—停止程序后再次启动程序,而不关闭程序,java,exception,exception-handling,Java,Exception,Exception Handling,我有一个Java程序,用来显示通过网络发送给用户的流量信息。目前,用户必须单击“开始”按钮开始接收和查看该信息,然后单击“停止”按钮停止接收该信息 但是,由于我的代码目前的状态,它只会在用户第一次单击“开始”按钮时起作用。。。单击“停止”后,如果再次尝试单击“启动”,将显示控制台错误,显示: 线程“AWT-EventQueue-0”java.util.concurrent.RejectedExecutionException中出现异常:任务。。。已从java.util.concurrent.Th
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");
}
}
});