簡體   English   中英

如何優雅地停止在 eclipse 中運行的 java 主程序

[英]How to gracefully stop a java main program running inside eclipse

我在 eclipse(java main 方法程序)中運行一個腳本,它創建線程,其中每個線程處理一個 Excel 工作表,然后將處理后的數據保存到數據庫中。 從 2 天起它一直在處理數據,今天突然我在處理完 excel 中的每條記錄后打印的日志停止了。

經過一些檢查發現 mongodb 變得無響應,因此我認為所有線程都在等待響應。 我重新啟動了我的數據庫,認為程序會拋出錯誤,但沒有拋出錯誤。

我的代碼的編寫方式是,在處理完一張完整的工作表后,它會在 Excel 工作表記錄中寫入一條狀態消息。 這部分代碼寫在 finally 塊中。 我一直在等待程序自行終止,但它仍在運行。 我已經檢查它正在運行,因為我從用戶那里獲取輸入以讀取新的 Excel 表。 它從用戶那里獲取輸入並打印日志。 因此,我認為該程序並沒有變得無響應。

有沒有辦法安全地關閉我的程序,以便所有狀態日志都打印到 Excel 表中。 我的意思是確保 finally 塊中的代碼得到執行。 腳本中沒有編寫關閉掛鈎。 狀態日志非常重要,因為我自過去 2 天以來一直在運行該程序。

根據此鏈接,使用 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”方法中沒有調用睡眠或等待方法。 validate 方法是從線程類重寫的 run() 方法調用的。

添加了一部分 jstack 輸出::

“附加監聽器”#13759 守護進程 prio=9 os_prio=0 tid=0x00007fddd0001000 nid=0x11ba 等待條件 [0x0000000000000000] java.lang.Thread.State: RUNNABLE

鎖定的可擁有同步器: - 無

"ThreadID:13" #12918 prio=5 os_prio=0 tid=0x00007fde1c89f000 nid=0x155 runnable [0x00007fdde8bec000] java.lang.Thread.State: 在 java.net.SocketInputStreamInput0(java.net.SocketInputStream Method.socket.) RUNNABLE .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) at java.io.BufferedInputStream.read1(BufferedInputStream.java:286) at java.io.BufferedInputStream.read(BufferedInputStream.java:345) - 在太陽處鎖定 <0x0000000760ccd5b8>(一個 java.io.BufferedInputStream)。 net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704) at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0( HttpURLConnection.java:1536) - 在 sun.net.www.protocol.http.HttpURLConnection.getInp 鎖定 <0x0000000760cc9168>(一個 sun.net.www.protocol.http.HttpURLConnection) utStream(HttpURLConnection.java:1441) - 在 org.glassfish.jersey.client 的 java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) 鎖定 <0x0000000760cc9168>(一個 sun.net.www.protocol.http.HttpURLConnection) .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) 在 org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:664) 在 org.glassfish.jersey.internal.Errors。 process(Errors.java:315) at org.glassfish.jersey.internal.Errors.process(Errors.java:297) at org.glassfish.jersey.internal.Errors.process(Errors.java:228) at org.glassfish .jersey.process.internal.RequestScope.runInScope(RequestScope.java:424) at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:664) at org.glassfish.jersey.client.JerseyInvoc ation$Builder.method(JerseyInvocation.java:399) 在 org.glassfish.jersey.client.JerseyInvocation$Builder.get(JerseyInvocation.java:303) 在 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)

鎖定的可擁有同步器: - 無

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

我基於你給出的那一行經過一些檢查發現 mongodb 變得沒有響應,因此我假設所有線程都在等待響應。

當你想關機時,你可以在控制台輸入一個字符

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM