Multi Threading —Basics Explained in simple way

Vinod Kumar Gorrepati
5 min readSep 2, 2022

--

In this article, I will be trying to give a quick overview of multithreading and where to implement and how to implement. If you are a beginner, this is the starting point to know what multi threading is all about.

In java, when we start running the main method, JVM by default in background creates a main thread for you where it executes the program. This is called main thread.

What is a Thread?

It is nothing but the path taken to execute a program. Just as we are reading this article line by line, the JVM also reads and executes your code line by line in the main method.

What is the difference between Process and Thread?

A program in execution is nothing but a process. Process can have multiple threads running in it. Process can also be termed as Thread. But thread cannot be called process. Confusing?? OK. Let’s see an example. Open a Chrome Browser is nothing but a process. You started searching on a tab for URL and this is running on a thread. If you open other tab and start searching for other topic simultaneously then one more thread is created. So in single process we can have multiple threads.

How to create a Thread?

You can make a class as Thread class by extending the Thread class or implementing Runnable Interface.

public class MyThread extends Thread {

public void run(){
System.out.println("MyThread running");
}
}

Now we can call MyThread and start the thread as follows:

MyThread myThread = new MyThread();
myThread.start();

The start() call will return as soon as the thread is started. It will not wait until the run() method is done. The run() method will execute as if executed by a different CPU. When the run() method executes it will print out the text "MyThread running".

We can also create anonymous class of thread as follows:

Thread thread = new Thread(){
public void run(){
System.out.println("Thread Running");
}
}

thread.start();

Let us see how we can implement same functionality using Runnable interface

public class MyRunnable implements Runnable {

public void run(){
System.out.println("MyRunnable running");
}
}

If we switch to anonymous class for the same

Runnable myRunnable =
new Runnable(){
public void run(){
System.out.println("Runnable running");
}
}

Using Lambda expressions, this is further simplified

Runnable runnable =
() -> { System.out.println("Lambda Runnable running"); };

To start the thread of runnable interface we have to pass the Runnable instance to the Thread class

Thread thread = new Thread(runnable);
thread.start()

What are different Stages of Thread?

We have 5 different stages of Thread life cycle. When we created the thread the state is new. Now, I called my method start() this will start calling run(). During this process, the thread is in the state Runnable. Once the run() method is called, it starts the tasks on a thread. This moves it to running state.

While it is running, I can ask thread to rest for a while. For this, I use Thread.sleep(). The thread goes to the state blocked for the amount of time specified and then returns to runnable and then running.

Thread Life Cycle

what is the significance of join()

Suppose I have a program where I am running 2 threads say T1 and T2. At the end, I’m printing a statement “execution ended”. What is my output?

Just think, T1 is running a task and T2 is busy running other task. While these 2 threads are busy running the main thread is free and see that there is a statement which is at the end. So it executes the statement and prints execution ended even before the threads are completed.

This is not desired right? so, to overcome this, we have a method called join().

We can call t1.join() just before the statement. Now the main thread waits for the thread t1 to be completed and then starts executing the statement.

What if I have to update same variable from 2 threads at the same time?

Umm… I have learnt what is thread and how it works. I got a doubt. Suppose I have a variable say count and it is needed in 2 tasks which is executed by 2 different threads. My thread t1 increments the count in a loop 5 times and if t2 also updates the count at the same time in loop then while reading the value by t2 it might still not have latest value updated by t1. so we might get the conflicted output.

Do you have a solution for this?

Java found a solution. Yes, they introduced a keyword called synchronized. It locks the method until the thread releases it and so only one thread can act on it at one point of time. The other thread waits for it to get released and then takes its turn. In this way, we do not have conflicted output and everytime we access count we get the latest value.

Cool. Now I have got other problem. I have 2 variables x and y and which is updated in 2 different methods update_x() and update_y(). They both are marked as synchronized as suggested. In t1 my first statement is update_x() and so I locked the method and started updating. Meanwhile, thread t2 is executing a statement update_y(). Inside my update_x(), I’m calling update_y(), so now thread t1 is waiting for t2 to release update_y() method.

t2 is executing update_y() method is internally calling update_x() and starts waiting for the t1 to release. This goes to endless loop.

deadlock situation

This situation is called deadlock.

How to overcome deadlock situation?

  • Use the lock only for the objects/methods that is required. Avoid using for multiple objects
  • Provide a timeout, if the thread t1 could not acquire the lock even after waiting for certain time, we can throw an exception with proper message and exit from waiting for the method.
  • Avoid using join() which waits for the other thread to finish for indefinite time period.
  • Avoid nested locks. If we had already given lock to one thread, avoid giving lock to other threads

As of now, we are good with basics of Multi Threading. Lets go bit deeper in our next article. Keep Reading..!! Stay Updated..!!

--

--