Single Threading in JS

Single Threading in JS

Javascript is a single threaded language...

Β·

5 min read

Here we explore the peculiar single-threaded nature of JavaScript and how it is different from other languages like Java which are multi-threaded. So buckle up and get ready for this tech-ride !!! πŸ™ˆπŸ™ˆπŸ™ˆ


πŸ΄β€β˜ οΈ What is a thread ?

  • A thread in computer science is the execution of running multiple tasks or programs at the same time.
  • You can say that a thread is like a process which executes multiple operations line by line in a sequential fashion.

th1.png

  • The main thread is where a browser processes user events and paints. By default, the browser uses a single thread to run all the JavaScript in your page, as well as to perform layout, reflows, and garbage collection. This means that long-running JavaScript functions can block the thread, leading to an unresponsive page and a bad user experience.

☠️ How is JS single-threaded ?

  • Javascript engine runs on a V8 engine that has a memory heap and a call stack.
  • JS is a single threaded which means only one statement is executed at a time.
  • In other words, we can say JS is by default synchronous in nature.
  • Synchronous (or sync) execution usually refers to code executing in sequence. In sync programming, the program is executed line by line, one line at a time. Each time a function is called, the program execution waits until that function returns before continuing to the next line of code.

Let us take the below example :

console.log('Hi There!');

console.log('My Name is');

console.log('Manik!');

th1.JPG

In the above code, each statement executes line by line making it synchronous.

🦜 So deep down how does single-threading work in JS ?

  • Javascript is a single threaded language that can be non-blocking.
  • Single threaded means it has only one call stack. Whatever is on the top of the call stack is run first.

Let us take the below example :

function call(){
    console.log('Hi There!');
    function me(){
        console.log('My Name is');
        function soon(){
            console.log('Manik!');
        }
        soon();
    }
    me();
};

call();

th1.JPG

Now please look closely how this works within the call stack as is pretty evident on the browser console's debugger window :

debug1.JPG debug2.JPG

stack.png

So in the above code as you may see, the function calling works like a stack : LIFO way - Last In, First Out. This means at the beginning of the code, 'call()' gets pushed in the stack, then 'me()' is pushed and finally 'soon()' is pushed.


βš“ Blocked Call Stack in JS

  • The synchronous behavior of JS may cause a problem as it may unnecessarily block further execution of the program.

Let us take below example :

console.log('A');

for(i=0; i<= 100000000000000000000000; i++){};
console.log('B');

console.log('C');

In the above code, if a portion of code needs heavy execution, this may cause the whole program execution to get blocked. This would create a problem considering the single-threaded nature of JS.


🀠 Asynchronous Behavior

  • JS can also be non-blocking and behave as if it were multi-threaded.
  • It means that it doesn't wait for the response of an API call, I/O events, etc., and can continue the code execution.
  • Asynchronous (or async) execution refers to execution that doesn’t run in the sequence it appears in the code. In async programming the program doesn’t wait for the task to complete and can move on to the next task.
  • Different languages have different ways to implement asynchronous. The most popular is through Multi-threading.
  • In brief, Java implements multi-threading by creating a child thread which does it’s own separate execution and then merges back with the parent thread.
  • This however can run into a problem known as Deadlock, which can be dealt with various deadlock prevention mechanism.

Let us see from below example, how asynchronous in JavaScript is implemented :

console.log('A');

setTimeout(() => {
    console.log('B');    
}, 3000);

console.log('C');

multith.JPG

In the above code, 'B' gets printed after 'C' as 'B' which may denote a very heavy process gets shifted to a timeout instruction.

  • In a nutshell, the asynchronous implementation in Javascript is done through a call stack, call back queue and Web API and event loop.

  • Call stack job as we seen earlier is to check what instruction is at the top of the stack and execute it. If there is an instruction like setTimeout() that requires extra time to execute then call stack will pop that out and send it to Web API.

  • The job of event loop is to continuously check if an event occurred, like mouse click or keyboard stroke so that it can send that to call stack. Of course, your mouse click will be given higher priority for execution than an image load.

stack2.png

  • In Javascript, All instructions are put on a call stack. When the stack arrives at setTimeout, the engine sees it as a Web API instruction and pops it out and sends it to Web API. Once the Web API is done with the execution, it will arrive at the call back queue.
  • The engine checks if the call stack is empty. If it is empty, then we check callback queue which has the instruction setTimeout in it. The callback queue sends it to call back stack and the instruction is executed.

So ending this article, highlighting the benefit of this procedure : JavaScript need not worry about how many cores or nodes a CPU is running on. There is only single call stack for this implementation.

πŸ‘±πŸ‘±πŸ‘± Happy Learning πŸ‘±πŸ‘±πŸ‘±

Β