如何优雅地停止在eclipse

时间:2016-10-04 11:58:56

标签: java eclipse multithreading

我在eclipse(java主方法程序)中运行一个脚本,该脚本创建线程,每个线程处理一个excel表,然后将处理后的数据保存到数据库中。自从2天以来它一直在处理数据,突然今天我从excel处理每个记录后打印的日志停止了。

经过一番检查后发现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();
                }
            }
        }
    }

内部没有调用sleep或wait方法&#34; validateAndProcessData&#34;方法。 从线程类重写的run()方法调用validate方法。

添加了jstack输出::

的一部分

&#34;附加听众&#34; #13759 daemon prio = 9 os_prio = 0 tid = 0x00007fddd0001000 nid = 0x11ba等待条件[0x0000000000000000]    java.lang.Thread.State:RUNNABLE

锁定可拥有的同步器:      - 没有

&#34;线程ID:13&#34; #12918 prio = 5 os_prio = 0 tid = 0x00007fde1c89f000 nid = 0x155 runnable [0x00007fdde8bec000]    java.lang.Thread.State:RUNNABLE     在java.net.SocketInputStream.socketRead0(本机方法)     在java.net.SocketInputStream.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)     在java.io.BufferedInputStream.read1(BufferedInputStream.java:286)     在java.io.BufferedInputStream.read(BufferedInputStream.java:345)      - 已锁定&lt; 0x0000000760ccd5b8&gt; (一个java.io.BufferedInputStream)     在sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704)     在sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647)     at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1536)      - 已锁定&lt; 0x0000000760cc9168&gt; (a sun.net.www.protocol.http.HttpURLConnection)     at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)      - 已锁定&lt; 0x0000000760cc9168&gt; (a sun.net.www.protocol.http.HttpURLConnection)     在java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)     在org.glassfish.jersey.client.HttpUrlConnector._apply(HttpUrlConnector.java:321)     在org.glassfish.jersey.client.HttpUrlConnector.apply(HttpUrlConnector.java:227)     在org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:246)     在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)     在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)     在org.glassfish.jersey.client.JerseyInvocation $ Builder.method(JerseyInvocation.java:399)     在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(ExcelSheetsValidator.java:137)     at transaction.script.excelSheet.validators.ExcelSheetsValidator.run(ExcelSheetsValidator.java:122)     在java.lang.Thread.run(Thread.java:745)

锁定可拥有的同步器:      - 没有

2 个答案:

答案 0 :(得分:0)

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

我基于你给出 的行,经过一些检查后发现mongodb没有响应,因为我假设所有线程都在等待响应。

答案 1 :(得分:0)

要关闭时可以在控制台中输入一个字符

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);
}