Search code examples
javamultithreadingjava-threads

Order in which our source code is run when using different threads


When I first started learning about Java, I learnt that code is read from top to bottom. No need to make a code to cover that explanation as I guess you all understand it.

But what happens when I am using multi-threading? Say I have this simple example:

public class Tester {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 5; i++) {
            executorService.execute(new WorkingClass());
        }
        System.out.println("rest od code..");
        executorService.shutdown();
    }
}

class WorkingClass implements Runnable{
    @Override
    public void run() {
        System.out.println("working");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

I am using singleThreadExecutor, so 1 thread should do those 5 tasks. I was expecting that my for loop would run first, printing at least one "working" before printing "rest od code.." in console. I was wrong. My result is always this:

rest od code..
working
working
working
working
working

Can someone tell me how isn't at least one 'working' printed in console before 'rest of code'? Is it possible that code run so fast that it didn't get a chance to actually run any run() method before reaching ('rest of code')?

[NOTE] Any edit would be appreciated to help improve this question.


Solution

  • Different threads run independently. There are no guarantees about relative order between your main thread and any of the 'Runnables' it creates.

    This is nothing to do with whether code is 'read' from top to bottom; that's not a useful concept for execution. Here is a trivial non-thread example of non-top-to-bottom execution:

       void method1() {
           method2();
           System.out.println("one");
       }
    
       void method2() {
           System.out.println("two");
       }
    

    Back to the issue at hand: you'll notice the documentation for 'execute' refers to running the Runnable at 'some time in the future'.

    In reality, that's probably something like putting an entry on a queue and then waking up a thread. Getting the thread up and running typically takes more machine instructions that the straight-line code path.

    So, yes, your 'runs so fast' explanation is more-or-less on the mark, except that 'so fast' isn't really blindingly fast.