如何优雅地停止在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)

锁定的可拥有同步: - 无

+1

请显示您的代码 –

+0

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

+0

使用'jstack'来获取堆栈跟踪。这样你可以找出程序卡在哪里。 – talex

您可能已经尝试了这一点,但我猜如果您对数据库连接超时有某种异常处理,它可能会解决您的问题。

我你在哪里给经过一番检查后发现,MongoDB中已经变得没有反应,由于我以为所有的线程都在等待响应行立足这一点。