DEV Community

loading...
Cover image for Multi-threading and  Parallel Programming

Multi-threading and Parallel Programming

Kwerenachi Utosu
I speak Java, Python and I'm enthusiastic about Artificial Intelligence and Data Science
・5 min read

Multi-threading is a widespread programming and execution model that allows multiple threads to exist within the context of one process. Each of these threads can run in parallel and these thread share similar address space. Okay let's start from the very beginning.

What is a Thread?

A thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler, which is typically a part of the operating system. Most times a thread exist within the process and multiple threads can exist within a single process, hence multi-threading.

Alt Text

I'd say a Computer Scientist would see A Thread the same way a Chemist would see an An Atom .

These threads run concurrently and they share resources. The implementation of threads and processes differ between operating systems, but in most cases a thread is a component of a process.

What is a Process?

Processes are instances of programs which typically run independent from each other. For Example, if you start a Java program the operating system spawns a new process which runs in parallel to other programs. Inside those processes we can utilize threads to execute code concurrently, so we can make the most out of the available cores of the CPU.

Alt Text

Unlike Threads, processes do not share resource with one another. A process is a unit of resources, while a thread is a unit of scheduling and execution.

Thread Pool

Creating a brand-new OS thread requires memory allocation and CPU instructions in order to set it up and also kill it down. In order to better handle the usage of a thread and also avoid the creation of new ones, the operating systems or platforms reckon with a Thread Pool feature, which allows the application to take an already existing thread to use.

That’s a much more efficient way to handle multiple threads without dealing with its creation or destruction. Furthermore, the OSs know when a thread from the thread pool is not actively in use thus, they can automatically “skip” it during the threads’ iteration.

Descriptive Programming Representations Of Threads

We'd take a look at threads as implemented from two classes in Java, Executors and Runnable.

  • Executors Executors as a class in Java that abstracts most of the manual thread creation process. They are capable of running asynchronous tasks and typically manage a pool of threads, so we don't have to create new threads manually.

The class Executors provides convenient factory methods for creating different kinds of executor services. In the sample below we use an executor with a thread pool of size one.

Alt Text

The result looks similar to the above sample but when running the code you'll notice an important difference, the java process never stops! Executors have to be stopped explicitly - otherwise they keep listening for new tasks.

An ExecutorService provides two methods for that purpose: shutdown() waits for currently running tasks to finish while shutdownNow() interrupts all running tasks and shut the executor down immediately. This service is mostly used when working with socket connections, to facilitate asynchronous calls(Sink-Source connections).

  • Runnable A Runnable is functional interface defining a single void no-arguments method run(). Before starting a new thread you have to specify the code to be executed by this thread, often called the task and this is done by implementing a Runnable. Note that, you can have as many tasks as possible.

Alt Text

For the example above, we utilize Java 8 lambda expressions to print the current threads name to the console. First we execute the runnable directly on the main thread before starting a new thread. See the sample outputs below.

Hello main
Hello Thread-0
Done!
Enter fullscreen mode Exit fullscreen mode

Or that:

Hello main
Done!
Hello Thread-0
Enter fullscreen mode Exit fullscreen mode

We have two possible outputs because due to concurrent execution we cannot predict if the runnable will be invoked before or after printing Done. The order is non-deterministic, thus making concurrent programming a complex task in larger applications. Although Threads can also be put to sleep for a certain duration.

Multi-threading in-depth

Like we've clearly stated earlier, A multi-threaded program contains two or more parts that can run concurrently and each part can handle a different task at the same time making optimal use of the available resources specially when your computer has multiple CPUs.

Alt Text

Multi-threading extends the idea of multitasking into applications where you can subdivide specific operations within a single application into individual threads. It enables you to write in a way where multiple activities can proceed concurrently in the same program.

There are a handful of programming languages that give room for multi-threading, and most of the languages are Object Oriented Programming languages(OOP). Languages like Java, C,C++ and even .NET frameworks. Some other interpreted languages also made the cut, like Ruby MRI for Ruby and CPython for Python. If you were waiting to see Javascript, well you won't because JavaScript does not support multi-threading and that's because the JavaScript interpreter in the browser is a single thread.

Heavily Multi-threaded Applications

Almost all well-built applications support multi-threading. Let's look at browsers. Most browsers are multi-threaded from firefox to Safari to Chrome and many others. But today we'd talk more about Chrome.

Google Chrome
Chrome has a multi-process architecture and each process is heavily multi-threaded. The main goal is to keep the main thread (“UI” thread in the browser process) and IO thread (each process’ thread for handling IPC) responsive. This means offloading any blocking I/O or other expensive operations to other threads.

Alt Text

In Chrome, each and every tab you open gets its own content process. Five tabs, 5 processes, one hundred tabs, 100 processes. This approach maximizes performance, but you pay a hefty penalty in memory consumption and battery life. Ever wondered why the CPU consumption for Chrome on your task manager is always high? Well, here you go.

Every chrome process has,

  • A main thread This thread updates the UI and runs most of Blink.
  • An IO thread This thread handles IPCs and network requests
  • A few more special-purpose threads.
  • A pool of general-purpose threads.

Chrome Compared to Firefox
While Chrome creates a content process for each tab, Firefox instead spins up to four content process threads by default. In Firefox, the first 4 tabs each use those 4 processes and additional tabs then use threads within those processes. Multiple tabs within a process share the browser engine that already exists in memory, instead of each creating their own.

Threads Vs Processes

Threads are different from the conventional multitasking process in so many ways:

  • Processes are typically independent, while threads exist as subsets of a process.
  • Processes carry considerably more state information than threads, whereas multiple threads within a process share process state as well as memory and other resources.
  • Processes have separate address spaces, whereas threads share their address space.
  • Processes interact only through system-provided inter-process communication mechanisms.
  • Context switching between threads in the same process typically occurs faster than context switching between processes.

Parallelism

Parallelism relate to the concept were the work is distributed in multiple units, in such a way that it doesn't compromise the final product but minimizing the total execution time.

Parallel execution is the ability of two (or more) tasks to run at the very same time. While Concurrency stands for the possibility, Parallelism is the reality.

Conclusion

Multithreading is now an important part of modern software development. It’s supported by many programming languages and platforms and goes all the way down to the operating system. Knowing how to work with multiple threads can definitely lead developers to build better applications.

Discussion (4)

Collapse
jcodingclub profile image
James J

Your posts are quite exceptional. Was able to gain much from this, thanks alot...

Collapse
kwereutosu profile image
Kwerenachi Utosu Author

Happy to have helped

Collapse
alxgrk profile image
Alexander Girke

Nice post, I especially liked your in-depth part 👏

Collapse
kwereutosu profile image
Kwerenachi Utosu Author

Thank you