Multithreading in Java

Multithreading in Java

In this article we’ll be learning about multithreading concept in Java. But before we proceed with multithreading let’s understand what threads in Java are. Now threads is something which is one of the most important topics in Java.

We’ll learn about the following topics in this article:

  • what is a Java thread?
  • what is thread life-cycle?
  • how we can create a thread
  • what is main thread in a Java application
  • multithreading

Java Thread

In layman’s language a Java thread is simply a lightweight sub process. So, when the application is running the operating system creates a process. Java Virtual Machine will take care of Java applications, so process would be created and each and every process will have a main thread. A java thread is the smallest independent unit of a program which contains a separate path of execution. The main thread in java is an execution context where certain jobs are executed one after the other in a sequence. A thread in java is created and controlled by java.lang.Thread class which is present by default in the lang package.

Java Thread Life-Cycle

When we create a thread, it will have a life-cycle. A thread can lie only in one of different states at any point of time. Typically, a thread will be in a new state when it is created then it moves to the runnable and then to the running state. Finally, the thread will end in a terminated state. In between a thread can have a waiting state which can iterate between runnable and running state.

Multithreading

Let’s understand these states individually.

1.New State: In this state a new object of a thread is initiated. A new thread begins its life-cycle in this state & remains here until the program starts the thread. We can also say that a thread is born in this state which is why it is also called born thread.

2.Runnable State: Once a thread is created we can start the thread. A thread stays in this state until it is executed. After starting the thread, it comes under runnable state.

3. Running State: In this state a thread is running which means it is executing a run () method from thread class and we have the yield() method that can send the thread back to the runnable state again.

4.Waiting State: When a thread enters a state of inactivity such that it is not performing any action it is known as waiting state. In this state the thread waits for some other thread to give back the data or it is sleeping or blocked at certain scenario or a use case.

5.Terminated State: When the thread has completed its task after execution it is known as terminated state.

Learn Core Java

Let’s understand the threads with the help of an analogy. Suppose we want to download an image from a server. Now threads are typically used when we have to perform a long running operation. Downloading an image seems to be a simple operation but it can be a long running operation because it is dependent on the network speed. When downloading an image, we create a new thread, and, in the background, we’ll start fetching the bytes from the server and in running state the thread is continuously fetching the data. There can be a state called waiting when network connection gets disconnected. Now the thread can wait until the network connection is reestablished and it will get terminated if the image is properly downloaded.

Creating a Thread

We will now look into the process of creating a thread. Now if you want to create a thread you need to understand the purpose for creating the thread. By default, we have a main thread in our application that is represented by the main() method. Whenever we run our java application we write our code in the main() method and the code in the main() method is executed as the main thread itself. Therefore the main() method will contain the instructions within it and these instructions are executed as part of the main thread in a sequence. Now if a long running operation takes place within the main thread itself it can take time causing the low written instructions in the main() method to be blocked. Since the instructions are blocked the operating system will start giving messages to the user that the application is not responding and asks the user to wait or kill the application. Therefore for long running application we need to create a separate thread to remove the load from the main thread.

We can create a thread in two different ways, either we can extend the thread class or we can implement the runnable interface.

  1. Extend thread class
 public class Thread
     extends Object
         implements Runnable
  1. Runnable Interface
public interface Runnable

Creating a thread by extending a thread class

In this method if we create a thread class it will extend the thread. Once the thread class is created then we override the run() method and then we create object of the thread class. Finally we invoke the start() method which will internally execute the run() method.

public class MyFirstThread extends Thread {

public void run(){

    System.out.println(“First Thread…”);

}

public static void main(String[] args) {

    MyFirstThread obj = new MyFirstThread();

    obj.start();

}

Creating a thread with Runnable Interface

Many times, we use inheritance when our class is inheriting some other class. But it can’t inherit thread at the same time because multiple inheritance is not supported in java. So, if we are already extending a class we can’t extend a thread class, but we can create a thread with Runnable Interface. Rest of the process remains same like in extending a thread class. We override a run() method, create an object of the class and finally invoke the start() method.

public class MyFirstThread implements Runnable {

   public void run() {

        System.out.println(“My First Thread…”);

}

Public static void main(String[] args) {

    Thread t = new Thread(new MyFirstThread());

    t.start();

}

Java Main Thread

Main thread is the most important part of any application. Whenever we run an application the main thread is executed. A main thread is needed so that we can spawn or create the child threads. So, we can create child threads through main thread and start them. The main thread is the last thread to finish the execution i.e., the main thread terminates the program. Typically, JVM starts the main thread and other daemon threads at the same time. So, when an application is started the main thread and other daemon threads are started by JVM. The main thread can further start multiple child threads and the child threads can start further threads.

Multithreading

Controlling Main Thread

The main thread can be controlled by calling the currentThread() method from thread class. With this method a reference is returned to the main thread on which it is called.

public class Test extends Thread

{

   public static void main(String[] args)

   {

     // getting reference to Main thread

     Thread t = Thread.currentThread();

 

     // getting name of Main thread

     System.out.println("Current thread: " + t.getName());

 

    // changing the name of Main thread

    t.setName("Domino");

    System.out.println("After name change: " + t.getName());

 

    // getting priority of Main thread

    System.out.println("Main thread priority: "+ t.getPriority());

 

    // setting priority of Main thread to MAX(10)

    t.setPriority(MAX_PRIORITY);

 

     System.out.println("Main thread new priority: "+      t.getPriority());



    for (int i = 0; i < 5; i++)

    {

       System.out.println("Main thread");

    }

 

    // Main thread creating a child thread

    ChildThread ct = new ChildThread();

 

    // getting priority of child thread

    // which will be inherited from Main thread

    // as it is created by Main thread

    System.out.println("Child thread priority: "+ ct.getPriority());

 

    // setting priority of Main thread to MIN(1)

    ct.setPriority(MIN_PRIORITY);

 

    System.out.println("Child thread new priority: "+   ct.getPriority());

 

    // starting child thread

    ct.start();

    }

}

 

// Child Thread class

class ChildThread extends Thread

{

    @Override

    public void run()

    {

      for (int i = 0; i < 5; i++)

      {

          System.out.println("Child thread");

      }

   }

}

Output:

Current thread: main

After name change: Domino

Main thread priority: 5

Main thread new priority: 10

Main thread

Main thread

Main thread

Main thread

Main thread

Child thread priority: 10

Child thread new priority: 1

Child thread

Child thread

Child thread

Child thread

Child thread

Multithreading in Java

Now multithreading is a process to execute multiple threads concurrently. It is worth mentioning here that both multithreading and multiprocessing are used to perform multitasking. Whereas multitasking is a process to execute the multiple tasks concurrently.

Learn Advanced Java Training

Few of the advantages of multithreading are:

1.In multithreading the threads are independent so that each thread does not affect other thread.

2.It helps in saving CPU usage as threads share the common memory area

3.With the help of multithreading multiple operations can be performed simultaneously at the same time.

Let’s understand multithreading with the help of an example.

class Count implements Runnable
{   
  Thread mythread ;   
  Count()   
  {       
    mythread = new Thread(this, "my runnable thread");                                            
    System.out.println("my thread created" + mythread);             
    mythread.start();  
  }   
  
  public void run()  
  {      
    
    try      
    {        
       for (int i=0 ;i<10;i++)       
       {          
         System.out.println("Printing the count " + i);              
         Thread.sleep(1000);       
       }     
    } 
    
    catch(InterruptedException e)     
    {        
      System.out.println("my thread interrupted");     
    }     
    
    System.out.println("myfirstthread run is over" );   
    }
}


class RunnableExample
{    
  public static void main(String args[])    
  {       
  Count cnt = new Count();       
  
  try       
  {          
    while(cnt.mythread.isAlive())          
    {            
      System.out.println("Main thread remains alive till the child thread is live");             
      Thread.sleep(1500);          
    }       
  }       

  catch(InterruptedException e)       
  {          
    System.out.println("Main thread interrupted");       
  }       
 
  System.out.println("Main thread run is over" );    
  }
}

Output :

my thread createdThread[my runnable thread,5,main]
Main thread remains alive till the child thread is live
Printing the count 0
Printing the count 1
Main thread remains alive till the child thread is live
Printing the count 2
Main thread remains alive till the child thread is live
Printing the count 3
Printing the count 4
Main thread remains alive till the child thread is live
Printing the count 5
Main thread remains alive till the child thread is live
Printing the count 6
Printing the count 7
Main thread remains alive till the child thread is live
Printing the count 8
Main thread remains alive till the child thread is live
Printing the count 9
myfirstthread run is over
Main thread run is over

Like other Java methods multithreading is a powerful method but it takes time to master it. It is highly suggested that you should learn about the pros and pitfalls of using multithreading.

Leave a reply:

Your email address will not be published.

Site Footer