Prove that JavaScript runs in a single thread
Raja Jaganathan

Raja Jaganathan @rajajaganathan

About: JavaScript/TypeScript, React.js, Node.js developer

Location:
Chennai, India
Joined:
May 12, 2017

Prove that JavaScript runs in a single thread

Publish Date: Apr 5 '20
35 5

Alt Text

JavaScript runs on a single thread

we might hear about this sentence many times in different situations like interviews, blogs, conferences, workplaces, etc.

Is that really true?

Official docs say:

despite the fact that JavaScript is single-threaded — by offloading operations to the system kernel whenever possible.

This is again completely true for web browser too,

Of course, Yes it is, But can you prove that by writing some code?

Take a moment to think about this and demonstrate it with a code example.

Alt Text

Solution

let loop = true;

setTimeout(() => { 
    loop = false;
});

while (loop) {
    console.log('loop', loop);    
}

console.log('after loop');

Explanation:

We have just declared a variable called loop and it's defaulted to true.

setTimeout(() => {
    loop = false;
});

Immediately after the above line encountered by JavaScript interpreter, JavaScript scheduled a task in the event loop since these are web API. JavaScript doesn't want to block the main thread so it moves the task to event loop. Here are some of the web APIs which browser provides like XMLHttpRequest, setInternal, setTimeout, etc.

while (loop) {
    console.log('loop', loop);    
}

Here is an interesting moment in our example. As many developers know the above code will execute infinitely. But take a moment to think about what was happened to our scheduled task in the event loop. Will modify loop value as false ?.

Actually, It will never be loop false, because until the main thread execution is completed fully, the main thread won’t get the opportunity to pick a task from task queue in the event loop even though it’s completed and added callback in the task queue.

In other words, In general, the main thread will able to pick a completed task from task queue in the event loop, only after the main thread cleared all of its calls in the stack. Even though it was scheduled before reaching infinity code, no other threads can modify the loop's variable value.

So note that

console.log('after loop');

line is unreachable code.

Solution with Comments

let loop = true;

setTimeout(() => {  // callback execution is unreachable because main thread is still busy with below infinite loop code. 
    console.log('It will never reach here :ohh');
    loop = false;
});

while (loop) {
    console.log('loop', loop);  // Infinite loop
}

console.log('after loop');  // Unreachable code 

Hence it's running on a single thread.

Further Readings:

Comments 5 total

  • Anshul Negi
    Anshul NegiApr 5, 2020

    Thanks for sharing along with practical examples.
    If it is single-threaded then how it manages async behaviour?

    • rvilgalys
      rvilgalysApr 5, 2020

      JS has an event loop that allows for async execution on a single thread (the youtube talk at the end of the post is a great resource on this). IO and garbage collection are actually handled on different threads though.

      One advantage here is that other server languages dedicate a new thread per request and so end up bound to hardware limitations for even simple requests at high enough volume. Node.js allows you to scale up as needed (and being single threaded, it's easy to run many instances in parallel).

      • Anshul Negi
        Anshul NegiApr 6, 2020

        Ooo man I was in such a rush to finish this post that I missed the video link.
        Thanks for pointing out.

  • Curtis Fenner
    Curtis FennerApr 5, 2020

    This doesn't strictly prove that JavaScript is only run on a single thread, because concurrency is very subtle.

    In C++, this example (using, e.g., std::thread to start a second thread) might hang because there's no explicit synchronization of the loop variable, even though C++ can run on multiple threads

    In Go, this example (using go to start a goroutines) might hang because the thread scheduler isn't fair, and might never preempt the loop without a wait in it.

    Busy waiting is a bad idea in any language -- and it's why you should basically never notice that JavaScript is single threaded. The only way it should really affect your code is that you don't need mutexes/locks to protect 'critical sections' where you need to make many updates at once to be consistent

    • Raja Jaganathan
      Raja JaganathanMay 26, 2020

      Agreed!, it also confirms that both event loop and main thread running on a same thread.

Add comment