如何优雅地停止在eclipse中运行的java主程序
我在eclipse(java主要方法程序)中运行脚本,该脚本创建线程,其中每个线程处理Excel工作表并将处理后的数据保存到数据库中。自从2天以来,它一直在处理数据,突然今天记录了我在处理来自excel的每条记录后停止打印的日志。如何优雅地停止在eclipse中运行的java主程序
经过一些检查发现,mongodb变得没有响应,因为我认为所有的线程都在等待响应。我已经重新启动我的数据库,认为程序会抛出一个错误,但不会抛出错误。
我的代码写入的方式是在处理完整的工作表后,它会将状态消息写入Excel工作表记录。这部分代码写在一个finally块中。我一直在等待程序自行终止,但它仍在运行。我已检查它是否正在运行,因为我从用户那里输入了一个新的Excel表单来读取。它正在接受来自用户的输入并打印日志。所以我假设程序没有变得没有反应。
有没有办法可以安全地关闭我的程序,以便将所有状态日志打印到Excel表格中。我的意思是确保finally块内的代码得到执行。脚本中没有写入关闭钩子。状态记录非常重要,因为过去两天我一直在运行该程序。
根据这link使用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”方法中没有调用睡眠或等待方法。 验证方法是从线程类重写的run()方法中调用的。
加入jstack输出的一部分::
“附加监听器” #13759守护程序PRIO = 9 os_prio = 0 TID = 0x00007fddd0001000 NID = 0x11ba等待条件[0x0000000000000000] java.lang.Thread中。状态:RUNNABLE
锁定拥有同步器: - 没有
“线程ID:13” #12918 PRIO = 5 os_prio = 0 TID = 0x00007fde1c89f000 NID = 0x155可运行的[0x00007fdde8bec000] java.lang.Thread.State中: RUNNABLE在java.net.SocketInputStream.read(SocketInputStream.java:170) 上的java.net.SocketInputStream.socketRead(SocketInputStream.java:116) .SocketInputStream.read(SocketInputStream.java:141) at 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中) 在sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704) 在sun.net.www .http.HttpClient.parseHTTP(HttpClient.java:647)(sun.net.www.protocol.http.HttpURLConnection) at sun.net.www。 protocol.http.HttpURLConnection.getInputStream(HttpURLConnection类。的java:1441) - 锁定< 0x0000000760cc9168>(一个sun.net.www.protocol.http.HttpURLConnection) 在java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) 在org.glassfish.jersey.client。 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) at org.glassfish.jersey.client.JerseyInvocation $ 1.call(JerseyInvocation.java:664) at org.glassfish.jersey。 internal.Errors.process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process (Errors.java:297) 在org.glassfish.jersey.internal.Errors.process(Errors.java:228) 在org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:424) org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:664) at org.glassfish.jersey.client.JerseyInvocation $ Builder.method(JerseyInvocation.java:399) at org.glassfish.jersey.client .JerseyInvocation $ Builder.get(JerseyInvocation.java:303) at 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(Excel SheetsValidator.java:137) 在transaction.script.excelSheet.validators.ExcelSheetsValidator.run(ExcelSheetsValidator.java:122) 在java.lang.Thread.run(Thread.java:745)
锁定的可拥有同步: - 无
您可能已经尝试了这一点,但我猜如果您对数据库连接超时有某种异常处理,它可能会解决您的问题。
我你在哪里给经过一番检查后发现,MongoDB中已经变得没有反应,由于我以为所有的线程都在等待响应行立足这一点。
请显示您的代码 –
@NicolasFilotto我已添加部分代码 – Abhishek
使用'jstack'来获取堆栈跟踪。这样你可以找出程序卡在哪里。 – talex