Thread Synchronization in Java

When two or more threads try to access the same resource, they need somehow to ensure that the resource will be used by only one thread at a time.

The process by which this achive is called Synchronization. Java uses the concept of monitor (also called semaphore) for Synchronization.

The monitor allows one thread at a time to execute a Synchronized method. Only one thread at a time may hold a lock on a monitor.

For a thread can lock or unlock each object in Java is associated with a monitor.

Example: Write a program to synchronize a thread.

class Demo {
    void write(String msg) {
        System.out.print("[" + msg);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
        }
        System.out.println("]");
    }
}

class Caller implements Runnable {
    String msg;
    Demo obj;
    Thread t;

    public Caller(Demo obj1, String s) { // constructor
        obj = obj1;
        msg = s;
        t = new Thread(this);
        t.start();
    }

    public void run() {
        obj.write(msg);
    }
}



public class SynchronizedMain {
    public static void main(String args[]) {
        Demo obj = new Demo();
        Caller ob1 = new Caller(obj, "Hello");
        Caller ob2 = new Caller(obj, "Hi");
        Caller ob3 = new Caller(obj, "Students");

        // wait for threads to end
        try {
            ob1.t.join();
            ob2.t.join();
            ob3.t.join();
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
        }
    }
}
[Hi[Hello[Students]
]
]

In the above program, nothing exist to stop all three threads from entering write () method while other thread is using it.

These three threads are racing each other to complete the method and this condition is known as a race condition.

To fix this program, we must serialize access to write () method and restrict its access to only one thread at a time.

To do this, we simply need to write synchronized keyword before write () method definition. It is known as a synchronized method.

Synchronized Method

// synchronize calls to call()
  synchronized void write(String msg) {
      .....
}

above method write() can be changed as below

    synchronized void write(String msg) {
       System.out.print("[" + msg);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
        }
        System.out.println("]");
    }
}

Synchronized block: this technique is also used for thread synchronization

   //synchronize calls to call()
      void write(String msg) {
       synchronized(msg) {
         ...............
       }
}

using synchronization block we can change write method as below

  synchronized void write(String msg) {
       System.out.print("[" + msg);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
        }
        System.out.println("]");
    }
}

This prevent other threads from entering in write () method while other thread is using it. After synchronized has been added to write (), the output of the program.

Output:     

[Hi]
[Students]
[Hello]