Is there a way to print "noise3" before all the "Aroma" are printed? The rest of the main method always waits for the executorservice shutdown, but I want them to run simultaneously
import java.util.concurrent.*;
public class Class2 {
public static void main(String[] args) {
Runnable task = ()->{
for(int i=0;i<5;++i){
try { Thread.sleep(1_000); } catch (Exception e) { e.printStackTrace(); }
System.out.println("Aroma");
}
};
try(var service = Executors.newFixedThreadPool(5)){
for(int i=0;i<5;++i){
service.submit(task);
try { Thread.sleep(2_000); } catch (Exception e) { e.printStackTrace(); }
System.out.println("noise");
}
System.out.println("noise2");
}
System.out.println("noise3");
}
}
You asked:
print "noise3" before all the "Aroma" are printed
Your code as currently written does exactly the opposite of what you want.
ExecutorService#close
The try-with-resources code ends with an implicit call to ExecutorService#close
. That method blocks until all tasks assigned to the executor service resolve (or 24 hours elapse; see source code).
So your System.out.println("noise3");
cannot run until the call to ExecutorService#close
exits.
try( ExecutorService executorService = Executors.… )
{
…
}
// Flow-of-control blocks here until `ExecutorService#close` exits when all tasks resolve or 24-hours elapse.
System.out.println("noise3");
If you want "noise3" first, reverse the order of your code.
System.out.println("noise3"); // To execute first, place this code first.
try( ExecutorService executorService = Executors.… )
{
…
}
// Flow-of-control blocks here until `ExecutorService#close` exits when all tasks resolve or 24-hours elapse.
Tip: Always include that // Flow-of-control blocks here until
ExecutorService#close exits when all tasks resolve or 24-hours elapse.
comment in your code. It is crucial that anyone reading this code understands this issue.
Caveat: Be aware that output from System.out.println
does not appear on the console in chronological order when called across threads. At least include, and study, a timestamp (Instant.now()
) if you care about the sequence. Better yet, instead of System.out.println
, use a proper logging tool, or collect messages in a thread-safe SequencedCollection
.
Tip: Use var
only on simple, utterly obvious code. Threading and concurrency is not a place to be clever.
Similarly, use precise descriptive naming such as executorService
rather than service
.
I always write code with a thought to how it will read through blurry eyes during an 3 AM emergency debugging session.