2016-10-04 113 views
1

我在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)

鎖定的可擁有同步: - 無

+1

請顯示您的代碼 –

+0

@NicolasFilotto我已添加部分代碼 – Abhishek

+0

使用'jstack'來獲取堆棧跟蹤。這樣你可以找出程序卡在哪裏。 – talex

回答

0

您可能已經嘗試了這一點,但我猜如果您對數據庫連接超時有某種異常處理,它可能會解決您的問題。

我你在哪裏給經過一番檢查後發現,MongoDB中已經變得沒有反應,由於我以爲所有的線程都在等待響應行立足這一點。