Synchronization In Java

synchronization in java is defined as mechanism to control the access of multiple threads to any shared resource.In multithreading concept if multiple thread access or change same resource at the same time , then it may produce inconsistent or wrong result.So, different threads shouldn’t try to access or change data at same time.So , threads must be synchronized . If one thread writing data then other thread should be in waiting state,once thread one finished writing then only second thread should read it.

synchronization enables the lock on resource and allow only one thread to access it.

Synchronization can be applied to :

A Method

public synchronized withdrawAmount(int amount){…}

A Block Of Code

synchronied(objectRef){…}

-Synchronized methods in sub-classes use same lock as their super-classes.

-When one thread executing a synchronized method, all other threads that are trying to invoke that particular synchronized method or any other synchronized method of same object will have to wait.

Example Without Synchronization : Problem without synchronization in Java :

In below example we will understand problem without synchronization :

package com.crtr4u.sb;

public class ThreadSynDemo {
	public static void main(String[] args) {
		SBIAccount a1 = new SBIAccount();
		BankRunnable br = new BankRunnable(a1);
		Thread t1 = new Thread(br);
		Thread t2 = new Thread(br);
		t1.start();
		t2.start();
	}
}
class SBIAccount {
	int balance;
	SBIAccount() {
		balance = 10000;
	}

	public void withdraw(int amount) {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		balance = balance - amount;
		System.out.println("Remaining Balance " + balance);
	}
}

class BankRunnable implements Runnable {
	SBIAccount var;
	BankRunnable(SBIAccount obj) {
		var = obj;
	}

	@Override
	public void run() {
		var.withdraw(500);
	}
}

When we run above program we get output as :

Output :

Remaining Balance 9000
Remaining Balance 9000

which is not proper , because when first thread withdraw 500 that time Remaining Balance mush show as 9500 and for second thread it should be 9000 , here we are getting inconsistent balance because our withdraw method is not synchronized , lets make withdraw method synchronized as in below program :

Example using synchronization : Solution by using synchronization in java

package com.crtr4u.sb;

public class ThreadSynDemo {
	public static void main(String[] args) {
		SBIAccount a1 = new SBIAccount();
		BankRunnable br = new BankRunnable(a1);
		Thread t1 = new Thread(br);
		Thread t2 = new Thread(br);
		t1.start();
		t2.start();
	}
}
class SBIAccount {
	int balance;
	SBIAccount() {
		balance = 10000;
	}

	public synchronized void withdraw(int amount) {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		balance = balance - amount;
		System.out.println("Remaining Balance " + balance);
	}
}

class BankRunnable implements Runnable {
	SBIAccount var;
	BankRunnable(SBIAccount obj) {
		var = obj;
	}

	@Override
	public void run() {
		var.withdraw(500);
	}
}

Now in above example , our withdraw method is synchronized , so it will allow only one thread to act on it at one time and because of this synchronization we get correct output as below :

Output :

Remaining Balance 9500
Remaining Balance 9000

If you understood above example then I hope you got good understanding of the importance of synchronization in java.

In last article we read about Synchronized method in java , synchronized method lock only the statements which are there in method , but synchronized block lock whole object, always we have to keep synchronized block inside run method with object reference as below :

Syntax :

public void run(){

synchronized(sbiAccountObject){

sbiAccountObject.withdraw(500);

}

}

Example : Synchronized block in Java :

package com.crtr4u.sb;

public class ThreadSynDemo {
	public static void main(String[] args) {
		SBIAccount a1 = new SBIAccount();
		BankRunnable br = new BankRunnable(a1);
		Thread t1 = new Thread(br);
		Thread t2 = new Thread(br);
		t1.start();
		t2.start();
	}
}
class SBIAccount {
	int balance;
	SBIAccount() {
		balance = 10000;
	}

	public void withdraw(int amount) {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		balance = balance - amount;
		System.out.println("Remaining Balance " + balance);
	}
}

class BankRunnable implements Runnable {
	SBIAccount var;
	BankRunnable(SBIAccount obj) {
		var = obj;
	}

	@Override
	public void run() {
		synchronized(var) {
		var.withdraw(500);
		}
	}
}

Output:

Remaining Balance 9500
Remaining Balance 9000

Happy Learning.

Leave a Reply

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