Demystifying Dart: Execution Thread & Dart Call Stack
In this series, we will be deep diving into the world of Dart Programming Language; how it works behind the scenes, and why it works in a specific way.
Let’s start with a brief introduction of Dart Langauge. Dart is a multi-purpose static-typed programming language that is developed by Google. It was first released back in 2013 with version 1.0 coming out before it was used internally within Google to create web, servers, and Mobile Applications. Dart is an object-oriented, garbage-collected language with its syntax very much similar to C. Today, it’s very widely used in conjunction with Flutter to create beautiful-looking Mobile, Web, and desktop applications.
Dart, like many other programming languages, is a single-threaded language which means it can only run one thing at a time. It executes the code line by line which is also called Thread of Execution.
To understand how Thread of Execution works, Let’s understand it with the help of an example.
Before jumping onto the complex (relatively) part, let’s understand the code very quickly. In this code, we have two integers variables and two functions: One for multiplying the two numbers and one for taking the square of a number.
Now let’s understand how Thread of Execution will work. We already know that the main function is our starting point so the code execution will start from there.
Firstly, It will initialize the two variables: firstNumber and secondNumber in what’s known as global memory.
Next, there is a function implementation of the multiply function:
For this part, Dart will take the entire chunk of the code of the function and store it in the memory something like this:
Moving line by line, similar to the multiply function implementation:
Dart will do the same for the square function and store it in the global memory something like this:
Now as per Thread of Execution, Dart will move to the next line in which the variable multiplyResult is calling a function.
Here, since Dart cannot initialize this directly, it will create something which is known as the Dart Execution Thread . A Dart Execution Thread has its own local memory and set of executions. Something like this:
The Dart Execution Thread will execute the entire function body and will return back the value to the global memory from where it was initially called.
After the Dart Execution Thread is done with the execution, it will destroy itself.
Likewise, a similar Dart Execution Thread will be created for square function:
Just like the previous Dart Execution Thread, it will return back the value to the place from where it was called in the global memory. Pictorially it will be something like this:
Now If we take a step back and observe, we realize that the entire thing in itself is just another Dart Execution Context that is being executed to kickstart an application. Just like a normal Dart Execution Context, it had a memory and set of execution from the very start.
But there’s one mystery yet to be demystified, we know that Dart is a single-threaded language meaning there can only be one Thread of Execution active at any given time so how will Dart know which Thread is to execute in the main Execution Thread?
And that is exactly where the Dart Call Stack comes into action. The Call Stack is just like any other stack but this one holds the Threads of Execution that determines which thread will be executed in the Main Thread. Initially, If there is nothing else in the stack, there always is a main or global at the bottom of the stack.
But as soon as a new Dart Execution Thread is created, the thread is pushed into the Call Stack and after it’s done and destroyed, it will get popped out from the Call Stack too. Let’s visualize that with a diagram:
Just like this, the other threads will follow the same pattern and will get pushed and pop into the Stack over the course of their working.
If there are any nested methods, both will be added to the stack and will stay there until they’re done with their working and then they’ll be popped out of the stack respectively. The completion of the methods is identified with the return keyword.
That’s all for now Folks! This is first of many in the series. Thanks for reading this article ❤️
Clap 👏 If you learned something new today.
Feel free to post any queries or corrections you think are required ✔
Do leave feedback so I can improve on my content. Thank you! 😃
You can also Follow me on:
If you’re interested, here are some of my other articles: