[英]How to gracefully stop a java main program running inside eclipse
我在 eclipse(java main 方法程序)中运行一个脚本,它创建线程,其中每个线程处理一个 Excel 工作表,然后将处理后的数据保存到数据库中。 从 2 天起它一直在处理数据,今天突然我在处理完 excel 中的每条记录后打印的日志停止了。
经过一些检查发现 mongodb 变得无响应,因此我认为所有线程都在等待响应。 我重新启动了我的数据库,认为程序会抛出错误,但没有抛出错误。
我的代码的编写方式是,在处理完一张完整的工作表后,它会在 Excel 工作表记录中写入一条状态消息。 这部分代码写在 finally 块中。 我一直在等待程序自行终止,但它仍在运行。 我已经检查它正在运行,因为我从用户那里获取输入以读取新的 Excel 表。 它从用户那里获取输入并打印日志。 因此,我认为该程序并没有变得无响应。
有没有办法安全地关闭我的程序,以便所有状态日志都打印到 Excel 表中。 我的意思是确保 finally 块中的代码得到执行。 脚本中没有编写关闭挂钩。 状态日志非常重要,因为我自过去 2 天以来一直在运行该程序。
根据此链接,使用 kill -15 杀死程序会更安全,因为它可能会让程序执行一些清理操作,但我不确定。
public static void validate(String sheetNameWithLocation, String threadName) {
String fileName = sheetNameWithLocation.substring(sheetNameWithLocation.lastIndexOf("/") + 1);
Workbook workbook = null;
try (FileInputStream inputStream = new FileInputStream(sheetNameWithLocation);) {
workbook = new XSSFWorkbook(inputStream);
Sheet dataSheet = workbook.getSheet(AppConstants.DATA_SHEET);
if (dataSheet != null) {
String countryName = fileName.split("_")[0];
long startTime = System.currentTimeMillis();
for (int i = 1, count = 1; i <= dataSheet.getLastRowNum() && !shouldICleanUpAndStop; i++, count++) {
try {
validateAndProcessData(countryName, dataSheet, i, threadName);
} catch (Exception e) {
e.printStackTrace();
LOGGER.error(threadName + "::Exception occurred for record number:" + i + " Message is :: " + e.getMessage());
}
LOGGER.info(threadName + "::status is :: Processed " + count + " records in " + (System.currentTimeMillis() - startTime) + " ms");
}
LOGGER.info(threadName + "::Total time taken to process sheet is::" + (System.currentTimeMillis() - startTime) + " ms");
} else {
LOGGER.error(threadName + "::DATA sheet is not present. Program exiting....");
}
} catch (FileNotFoundException e) {
LOGGER.error("Unable to locate file");
e.printStackTrace();
} catch (IOException e) {
LOGGER.error("Unable to load or write to file.");
e.printStackTrace();
} finally {
if (workbook != null) {
try (FileOutputStream outputStream = new FileOutputStream(sheetNameWithLocation);) {
workbook.write(outputStream);
} catch (FileNotFoundException e) {
LOGGER.error("Unable to locate file");
e.printStackTrace();
} catch (IOException e) {
LOGGER.error("Unable to load or write to file.");
e.printStackTrace();
}
}
}
}
在“validateAndProcessData”方法中没有调用睡眠或等待方法。 validate 方法是从线程类重写的 run() 方法调用的。
添加了一部分 jstack 输出::
“附加监听器”#13759 守护进程 prio=9 os_prio=0 tid=0x00007fddd0001000 nid=0x11ba 等待条件 [0x0000000000000000] java.lang.Thread.State: RUNNABLE
锁定的可拥有同步器: - 无
"ThreadID:13" #12918 prio=5 os_prio=0 tid=0x00007fde1c89f000 nid=0x155 runnable [0x00007fdde8bec000] java.lang.Thread.State: 在 java.net.SocketInputStreamInput0(java.net.SocketInputStream Method.socket.) RUNNABLE .socketRead(SocketInputStream.java:116) 在 java.net.SocketInputStream.read(SocketInputStream.java:170) 在 java.net.SocketInputStream.read(SocketInputStream.java:141) 在 java.io.BufferedInputStream.fill(BufferedInputStream. java:246) at java.io.BufferedInputStream.read1(BufferedInputStream.java:286) at java.io.BufferedInputStream.read(BufferedInputStream.java:345) - 在太阳处锁定 <0x0000000760ccd5b8>(一个 java.io.BufferedInputStream)。 net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704) at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0( HttpURLConnection.java:1536) - 在 sun.net.www.protocol.http.HttpURLConnection.getInp 锁定 <0x0000000760cc9168>(一个 sun.net.www.protocol.http.HttpURLConnection) utStream(HttpURLConnection.java:1441) - 在 org.glassfish.jersey.client 的 java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) 锁定 <0x0000000760cc9168>(一个 sun.net.www.protocol.http.HttpURLConnection) .HttpUrlConnector._apply(HttpUrlConnector.java:321) at org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:227) at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246) at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:667) 在 org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:664) 在 org.glassfish.jersey.internal.Errors。 process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:228) at org.glassfish .jersey.process.internal.RequestScope.runInScope(RequestScope.java:424) at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:664) at org.glassfish.jersey.client.JerseyInvoc ation$Builder.method(JerseyInvocation.java:399) 在 org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:303) 在 transaction.script.excelSheet.validators.ExcelSheetsValidator.getlocation(ExcelSheetsValidator.java: 428) at transaction.script.excelSheet.validators.ExcelSheetsValidator.validateAndProcessData(ExcelSheetsValidator.java:231) at transaction.script.excelSheet.validators.ExcelSheetsValidator.validate(ExcelSheetsValidator.java:137) at transaction.script.excelSheet.validators.ExcelSheetsValidator .run(ExcelSheetsValidator.java:122) 在 java.lang.Thread.run(Thread.java:745)
锁定的可拥有同步器: - 无
您可能已经尝试过这个,但我想如果您对数据库连接超时有某种异常处理,它可能会解决您的问题。
我基于你给出的那一行经过一些检查发现 mongodb 变得没有响应,因此我假设所有线程都在等待响应。
当你想关机时,你可以在控制台输入一个字符
public static void main(String[] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
System.out.println("close");
}
});
SpringApplication.run(Application.class, args);
System.in.read();
System.exit(0);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.