簡體   English   中英

嘗試塊完成后,在Finally塊中延遲

[英]Delay in the Finally block after try block completion

我試圖運行以下並發代碼:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class TestThread {

public static void main(final String[] arguments) throws 
InterruptedException {
  ExecutorService executor = Executors.newSingleThreadExecutor();

  try {
     executor.submit(new Task());
     System.out.println("Shutdown executor");
     executor.shutdown();
     executor.awaitTermination(5, TimeUnit.SECONDS);
  } catch (InterruptedException e) {
     System.err.println("tasks interrupted");
  } finally {

     if (!executor.isTerminated()) {
        System.err.println("cancel non-finished tasks");
     }
     executor.shutdownNow();
     System.out.println("shutdown finished");
  }
 }

static class Task implements Runnable {

  public void run() {

     try {
        int duration = 6;
        System.out.println("Running Task!");
        TimeUnit.SECONDS.sleep(duration);
     } catch (InterruptedException e) {
        e.printStackTrace();
     }
  }
  }     
}

輸出是:

Shutdown executor
Running Task!
shutdown finished
cancel non-finished tasks
java.lang.InterruptedException: sleep interrupted

根據輸出,似乎最后跳過塊,並且首先執行finally塊之后的代碼,然后執行finally塊。 這是否與在try / catch塊完成后最終執行的代碼的正常流程相矛盾?

編輯:試過

System.out.flush();
System.err.flush();

按照其中一個建議進行每次打印但仍然輸出相同。

編輯:

我正在使用在線編譯器。

我想你會期望這兩條跟蹤被反轉,因為它們是以相反的順序聲明的:

關機完了

取消未完成的任務

我認為問題來自於System.errSystem.out的混合。
這些不是相同的流。 因此,他們的沖洗顯示都可以在不同的時間進行。

根據顯示輸出的應用程序/系統(IDE,OS命令行,在線編譯器/執行程序),至少有兩件事可能會產生排序問題:

  • 可以啟用或不啟用這些流的自動刷新
  • 在應用程序/系統的“輸出/控制台”中,這兩個流之間的跟蹤顯示順序可能不同步。

根據時間線顯示輸出的解決方法:

  • 每次print()調用后刷新流( System.out.flush()System.err.flush() )。
    它可能有效,但不能保證,因為寫入輸出的應用程序/系統可能無法通過時間線同步這兩個流的顯示。

  • 努力只使用System.out並僅在程序退出的錯誤情況下使用System.err 它將減少交錯的可能性。

  • 如果最后一個想法不合適,因為清楚地區分這兩種輸出很重要,使用一個日志庫(Logback或Log4j2,最好是在外觀中使用SLF4J),它允許精確地跟蹤信息(日期,時間,嚴重性級別,...... 。)並按程序流程時間軸的實際順序讀取它們。


這是僅使用System.out的相同代碼:
我添加了//1//2 ,...注釋輸出的預期順序。

public class TestThread {

    public static void main(final String[] arguments) throws InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        try {
            executor.submit(new Task());
            System.out.println("Shutdown executor"); // 1
            executor.shutdown();
            executor.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            System.out.println("tasks interrupted"); // not invoked because caught in Task.run()
        } finally {

            if (!executor.isTerminated()) {
                System.out.println("cancel non-finished tasks"); // 3
            }
            executor.shutdownNow();
            System.out.println("shutdown finished"); // 4
        }
    }

    static class Task implements Runnable {

        public void run() {

            try {
                int duration = 6;
                System.out.println("Running Task!");  // 2
                TimeUnit.SECONDS.sleep(duration);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

輸出現在正如預期的那樣,無論程序運行在哪里都應該是相同的:命令行,IDE,...

關機執行人

跑步任務!

取消未完成的任務

關機完了

java.lang.InterruptedException:睡眠中斷

注意 :

java.lang.InterruptedException:睡眠中斷

可能仍然在順序上有所不同,因為Throwable.printStackTrace()依賴於system.err

暫無
暫無

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

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