I am trying to run the below concurrency code:

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

and the output is :

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

According to the output it seems finally block is skipped and code after the finally block is executed first and later the finally block is executed. Doesn't this contradict the normal flow of the code which is finally gets executed after the try/catch block is complete?

EDIT : Tried

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

after every print as per one of the suggestions but still the same output.

EDIT:

I am using an online Compiler.

1 Answers 11

up vote 3 down vote accepted

I suppose that you expect that these two traces be reversed as these are declared in the reverse order :

shutdown finished

cancel non-finished tasks

I think that the issue comes from the mixing of System.err and System.out.
These are not the same streams. So both their flushing and their displaying may be performed at distinct times.

According to the application/system that displays the output (IDE, OS command line, online compiler/executor), at least 2 things may create an ordering issue :

  • the autoflush of these streams may be or not enabled
  • the displaying order of traces may not be synchronized between these two streams in the "output/console" of the application/system.

As workaround to display outputs according to the timeline :

  • flush the streams (System.out.flush() and System.err.flush()) after each print() invocation.
    It may work but no guarantee as the application/system that writes the output may not synchronize the displaying of these two streams through the timeline.

  • endeavor to use only System.out and use System.err only for error situations where the program will exit. It will reduce interleave possibilities.

  • if the last idea is not suitable because it matters to distinguish clearly the two kinds of output, use a logging library (Logback or Log4j2 preferably with SLF4J in facade) that allows to trace information with precision (date, time, severity level, ...) and to read them in the actual order of the program flow timeline.


Here is the same code that uses only System.out :
I added //1, //2,... comment for the expected order of the output.

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

The output is now as expected and it should be the same wherever the program is run : command line, IDE, ...

Shutdown executor

Running Task!

cancel non-finished tasks

shutdown finished

java.lang.InterruptedException: sleep interrupted

Note that :

java.lang.InterruptedException: sleep interrupted

may still differ in the order as it is written by Throwable.printStackTrace() that relies on system.err.

upvote
  flag
On top of that, I already expeirenced eclipse's Console View to fetch the data from those streams in portions instead of doing it instantly. – Izruo
upvote
  flag
"System.out.flush()" twice? Is that a Typo? – ghostrider
upvote
  flag
Yes, it is (copy-paste syndrome) . Thanks. – davidxxx
upvote
  flag
Did that still the same output.. – ghostrider
upvote
  flag
I am still getting the same output using your updated code. I am using an online compiler..Will that have any effect on the output? – ghostrider
1 upvote
  flag
The culprit is probably the online compiler. With IDE, you can have the same issue also. By using only System.out.println() you should however get the expected order. Did you try ? – davidxxx
upvote
  flag
Yes, that was the issue. Thanks the solution worked. – ghostrider
upvote
  flag
@davidxxx thanks..I am scraching my head on this : //allinonescript.com/questions/48240147/… It would be great if you could help – ghostrider
upvote
  flag
You are welcome. I did an answer for this other question. Interesting question I found. You didn't have useful answers and comments because you forgot the java tag ! Think of it the next time :) – davidxxx

Not the answer you're looking for? Browse other questions tagged or ask your own question.