Multithreading in java with example

Multithreading is one of the most important concept in core java. In this article we will learn what is multithreading? , what is the use of it? and What is the use of Synchronization and when to use it? with detailed examples.

At a time, two or more threads are accessing the same object is called as Multithreading in Java. First, we will create two threads for two objects. It is also possible to run two or more threads on a single class object. In this case, there is a possibility to get unreliable results.

If the two threads are perform same task, then they need same object to be executed each time. For your better understanding, take an example of any reservations like, railway, movie ticket booking,etc.

Let us think only one berth is available in a train and two passengers are asking for that berth. The first person has sent a request to allocate that ticket/berth to him. At the same time, the second person also sent a request to allocate that ticket/berth to him. Now, let us see to whom that berth is allocated.

Example: Write a program showing two threads acting upon a single object.

package com.javatbrains.threads;
//Thread unsafe - two threads acting on same object
class Reserve extends Thread{
     //Available berths are
     int available = 1;
     int wanted;
     //accept wanted berths at run time
     public Reserve(int i){
          wanted = i;
     }
    
     public void run(){
          //Display available berths
          System.out.println("Available berths= "+available);
          //available berths are more than wanted berths
          if(available>=wanted){
              //get the name of the person
              String name = Thread.currentThread().getName();
               //Allot the berth to him
              System.out.println(wanted +" Berth(s) reserved for "+name);
              try{
                   Thread.sleep(1500);//wait for printing the ticket
                   available = available-wanted;
                   //update the no. of available berths
              }catch (InterruptedException ie) {
                   ie.printStackTrace();
              }
          }else{
              //if available berths are less, display sorry
              System.out.println("Sorry! No berths available");
          }
     }
}

public class Unsafe {

     public static void main(String[] args) {
          //Tell that one berth is needed
          Reserve obj = new Reserve(1);
         
          //Attach first thread to the object
          Thread t1 = new Thread(obj);
          //Attach second thread to the same object
          Thread t2 = new Thread(obj);
         
          //take the thread names as persons names
          t1.setName("First Person");
          t2.setName("Second Person");
         
          //Send the request for berths
          t1.start();
          t2.start();
     }

}

OutPut:
     Available berths= 1
     1 Berth(s) reserved for First Person
     Available berths= 1
     1 Berth(s) reserved for Second Person

Please observe the output of the preceding program. It is absurd. It has allocated the same berth for two peoples. In this program, we have already taken available berths as 1. When thread t1 enters the run() method, it sees available number of berths as 1 and hence, it allots it to First person.

Then it enters into try{} block inside the run() method, where it will sleep for 1.5 seconds. In this time, ticket will be printed on the printer. When thread t1 is sleeping, thread t2 also enters the run() method, it also sees that there is 1 berth remaining. The reason is for this is that the available number of berths are not yet updated by the first thread. So that, thread t2 allots the same berth to the second person. Then the thread t2 also goes into sleep state. 

To solve these problem in java, there is a concept called synchronization. Synchronization will not allow the multiple thread accessing run() method at a time. 

Thread Synchronization

When a thread is already acting in an object,  preventing any other thread from acting on the same object is called 'Thread Synchronization' or 'Thread Safe'. The object on which the threads are  synchronized is called 'Synchronized object'. Synchronized blocks in java are marked with the 'synchronized' keyword. Thread synchronization is recommended when multiple threads are used on the same object(in  multithreading).

Synchronized object is like a locked object, locked on a thread. It is like a room with only one door. A person is entered into room and locked from it from behind. The second who wants to enter into the room should wait till the first person comes out. In this way, a thread also locks the object after entering it. Then the next thread cannot enter it till the first thread comes out. This means the object is locked mutually on threads. So, this objects is called 'mutex'(Mutually Exclusive lock).

How can we synchronize the object?
There are two ways of synchronize the object.
          1.  Using synchronized block: Here, we can embed a group of statements of the object with in a synchronized block,

    synchronized (object) {
        statements;
    }
         
In the above statement object represents the object to be locked or synchronized. The statements inside the synchronized block all are available to only one thread at a time.

           2.  Using synchronized keyword: we can synchronize an entire method by using synchronized keyword. For example, if we want to synchronize the code of display() method, then add the synchronized keyword before the method name.

     synchronized void display() {
          statements;
     }

Note: The main difference between synchronized block and synchronize keyword is, Synchronized block is useful to synchronize a block of statement. Synchronize keyword is useful to synchronize an entire method.

Example: Write a program to synchronize the threads acting on the same object.

package com.javatbrains.threads;
//Thread Synchronization - two threads acting on same object
class Reservation implements Runnable {

     // Available berths are
     int available = 1;
     int wanted;

     // accept wanted berths at run time
     public Reservation(int i) {
          wanted = i;
     }

     @Override
     public void run() {
          synchronized (this) {
              // Display available berths
              System.out.println("Available berths= " + available);
              // available berths are more than wanted berths
              if (available >= wanted) {
                   // get the name of the person
                   String name = Thread.currentThread().getName();
                   // Allot the berth to him
                   System.out.println(wanted + " Berth(s) reserved for " + name);
                   try {
                        Thread.sleep(1500);// wait for printing the ticket
                        available = available - wanted;
                        // update the no. of available berths
                   } catch (InterruptedException ie) {
                        ie.printStackTrace();
                   }
              } else {
                   // if available berths are less, display sorry
                   System.out.println("Sorry! No berths available");
              }
          }

     }

}

public class Safe {

     public static void main(String[] args) {
          // Tell that one berth is needed
          Reservation obj = new Reservation(1);

          // Attach first thread to the object
          Thread t1 = new Thread(obj);
          // Attach second thread to the same object
          Thread t2 = new Thread(obj);

          // take the thread names as persons names
          t1.setName("First Person");
          t2.setName("Second Person");

          // Send the request for berths
          t1.start();
          t2.start();
     }

}

OutPut:
     Available berths= 1
     1 Berth(s) reserved for First Person
     Available berths= 0
     Sorry! No berths available

Comments

Post a Comment

Popular posts from this blog

String interview questions and answers

JNDI configuration for Tomcat 9 with Oracle