Synchronization in Multithreading

When two or more threads need access to a shared resource, they need some way to ensure that the resource will be used by only one thread at a time. The process by which this is achieved is called synchronization.

In other words,

Thread Synchronization is defined as a mechanism which ensures that two or more concurrent processes or threads do not simultaneously execute some particular program segment known as critical section.

Key to synchronization is the concept of the monitor. A monitor is an object that is used as a mutually exclusive lock. Only one thread can own a monitor at a given time. When a thread acquires a lock, it is said to have entered the monitor. All other threads attempting to enter the locked monitor will be suspended until the first thread exits the monitor. These other threads are said to be waiting for the monitor. A thread that owns a monitor can reenter the same monitor if it so desires.

You can synchronize your code in either of two ways. Both involve the use of the synchronized keyword, and both are examined here.

Real Life example of thread safe

If you are having a bank account and you have two debit cards. Consider one card is being used by you and another is used by your wife. Your bank account balance is 5000. One day you need money and you go to ATM and at the same time your wife is also going to use their ATM. Now, if you both make transaction at same time for 2000 out of whole money. Now, what should happen? Should it show the remaining balance 3000?

Turns out, No!

Because, if you are allowed to do so at the same time without taken care your account will not be then synchronized with number of transactions you made.

To do so we should have taken care of synchronization.

Now let’s see a case when synchronization is not there:

// This program is not synchronized.

class Callme {

    void call(String msg) {

        System.out.print("[" + msg);

        try {

            Thread.sleep(1000);

        } catch(InterruptedException e) {

            System.out.println("Interrupted");

        }

        System.out.println("]");

    }

}
//creating a thread class implementing Runnable interface

class Caller implements Runnable {

    String msg;

    Callme target;

    Thread t;

    public Caller(Callme targ, String s) {

        target = targ;

        msg = s;

        t = new Thread(this);

       //starting thread

       t.start();

    }

    // implementing runnable method.

    public void run() {

        target.call(msg);

    }

}
//creating main class

class SynchController {

    //main method

    public static void main(String args[]) {

        Callme target = new Callme();

        Caller ob1 = new Caller(target, "Hello");

        Caller ob2 = new Caller(target, "Synchronized");

        Caller ob3 = new Caller(target, "World");

        // wait for threads to end

        try {

            ob1.t.join();

            ob2.t.join();

            ob3.t.join();

        } catch(InterruptedException e) {

        System.out.println("Interrupted");

    }

}

}

Here is the output produced by this program:

#Output : [Hello[Synchronized[World]

]

]

Note:   join( ) method wait for a thread to finish .This method waits until the thread on which it is called terminates. Its name comes from the concept of the calling thread waiting until the specified thread joins it. By calling join method our currently running thread waits for the joined thread to complete.

As you can see, by calling sleep( ), the call( ) method allows execution to switch to another thread. This results in the mixed-up output of the three message strings. In this program, nothing exists to stop all three threads from calling the same method, on the same object, at the same time. This is known as a race condition, because the three threads are racing each other to complete the method which can cause a program to run right one time and wrong the next.

To fix the preceding program, you must serialize access to call( ). That is, you must restrict its access to only one thread at a time. To do this, you simply need to precede call( )’s definition with the keyword synchronized, as shown here:

class Callme {

synchronized void call(String msg) {

...

This prevents other threads from entering call( ) while another thread is using it. After

synchronized has been added to call( ), the output of the program is as follows:

#output : [Hello]

[Synchronized]

[World]

 

2 Replies to “Synchronization in Multithreading”

Leave a Reply

Your email address will not be published. Required fields are marked *