我在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)
鎖定的可擁有同步: - 無
請顯示您的代碼 –
@NicolasFilotto我已添加部分代碼 – Abhishek
使用'jstack'來獲取堆棧跟蹤。這樣你可以找出程序卡在哪裏。 – talex