Java Thread Synchronization not working – Troubleshoot

The java thread synchronization is not working properly when the synchronized keyword is used to synchronize multiple threads to access a common resource. If the thread lock object is not correctly attached to the thread, the java thread synchronization will not work as expected.

Synchronization is a mechanism that won’t allow more than one thread for a resource at any point in time. Multiple threads attempt to access the same resource in multi-threaded environments, resulting in erroneous and unexpected results. Synchronization manages threads for sequential access to resources in order to avoid this.

Synchronization uses a locking mechanism to control threads to access a common resource at any point in time. Synchronized keyword lock an object for a thread and no other threads are able to lock it before the first thread is released. Improper coding to lock an object will result in a java thread synchronization failure.



Java Synchronization not working

The synchronised keyword is used to synchronise two or more threads to access a shared resource one thread at a time. In the following example, the synchronised keyword is used to synchronise two threads. But synchronisation doesn’t work as expected.

package com.yawintutor;

public class MyThread extends Thread {
	public Object lockingObject=new Object();

	public void run() {
		synchronized (lockingObject) {
			for (int i = 0; i < 3; i++) {
				System.out.println("Thread name : " + getName() + " count : " + i);
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
package com.yawintutor;

public class MyThreadMain {
	public static void main(String[] args) throws Exception {

		MyThread thread1 = new MyThread();
		thread1.setName("THREAD 1");
		thread1.start();

		MyThread thread2 = new MyThread();
		thread2.setName("THREAD 2");
		thread2.start();

	}
}

Output

Thread name : THREAD 1 count : 0
Thread name : THREAD 2 count : 0
Thread name : THREAD 2 count : 1
Thread name : THREAD 1 count : 1
Thread name : THREAD 2 count : 2
Thread name : THREAD 1 count : 2


Root Cause

Java synchronisation only works if the object is locked by all threads. If the java threads are locks for different instances of class objects, then the synchronisation will not work. All java threads should try to lock the same object, and if the lock is not available, the thread will wait until the lock is released. This will ensure the access sequence of the Java resource. If threads lock separate objects in the class, the synchronisation will not happen.



Synchronize using static object

The synchronised keyword is used to sync java threads. The synchronised keyword uses a java object to lock the thread and does not allow other threads to enter the synchronised block at the same time. If the locking object is a static object, a single instance of the object will be created. As a result, the synchronisation will work in java.

package com.yawintutor;

public class MyThread extends Thread {
	public static Object lockingObject=new Object();

	public void run() {
		synchronized (lockingObject) {
			for (int i = 0; i < 3; i++) {
				System.out.println("Thread name : " + getName() + " count : " + i);
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Output

Thread name : THREAD 1 count : 0
Thread name : THREAD 1 count : 1
Thread name : THREAD 1 count : 2
Thread name : THREAD 2 count : 0
Thread name : THREAD 2 count : 1
Thread name : THREAD 2 count : 2


Synchronize using String object

The java String is an immutable object. The java strings are created newly. The java string can not be modified, instead the modified string can be created.If two strings are assigned the same value of the string, both will point to the same memory address of the string. If the string is locked, all threads that attempt to lock the same string will wait until the lock is released.

package com.yawintutor;

public class MyThread extends Thread {
	public String lockingObject="test";

	public void run() {
		synchronized (lockingObject) {
			for (int i = 0; i < 3; i++) {
				System.out.println("Thread name : " + getName() + " count : " + i);
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Output

Thread name : THREAD 1 count : 0
Thread name : THREAD 1 count : 1
Thread name : THREAD 1 count : 2
Thread name : THREAD 2 count : 0
Thread name : THREAD 2 count : 1
Thread name : THREAD 2 count : 2


Synchronize using Constants

The java string constants that are created to access any where in the application. In this method , two separate thread implementations can be synchronised in Java. For example , if two threads a1, a2 are created using thread class A, and two threads b1, b2 is created using thread class B, then all four threads a1, a2, b1 , b2 can be synchronised using constant value.

package com.yawintutor;

public class Constant {
	public static String lockingObject="test";
}
package com.yawintutor;

public class MyThread extends Thread {
	public void run() {
		synchronized (Constant.lockingObject) {
			for (int i = 0; i < 3; i++) {
				System.out.println("Thread name : " + getName() + " count : " + i);
				try {
					sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

Output

Thread name : THREAD 1 count : 0
Thread name : THREAD 1 count : 1
Thread name : THREAD 1 count : 2
Thread name : THREAD 2 count : 0
Thread name : THREAD 2 count : 1
Thread name : THREAD 2 count : 2


Synchronize using Singleton Object

The singleton java object will make sure that one instance of the class is created. The singleton object can be used for java lock to synchronise java threads. The java threads will get the same singleton object that will be used to lock the synchronised block.



Related Articles

Leave a Reply

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