Java Synchronized Method not working – Troubleshoot

The java synchronized method is not working as expected when a java method is synchronized using the synchronized keyword to synchronize multiple threads to access the java method. If the java method lock is not correctly attached to the thread, the java method synchronization will not work as expected.

Java Method Synchronization is a mechanism that will not allow more than one thread to execute a java method at any point in time. Multiple threads attempt to execute the java method in multi-threaded environments, resulting in incorrect and unpredictable results. Method synchronization handles threads for sequential access to run a method in order to prevent this.

Synchronization uses a locking mechanism to control threads to access the java method at any point in time. Synchronized keyword lockes the java method for a thread and no other threads can lock it until the first thread is released. Improper coding to lock a java method will result in a java thread synchronization failure.



Java Synchronized Method not working

The synchronised keyword is used by the Java method to synchronise the Java method. The synchronised java method will be executed with a thread at a time. If another thread is attempting to execute the method, the lock in the synchronised method will not allow it to run and wait until the lock is released. The code below is using the synchronized method that is not working as expected.

package com.yawintutor;

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

public class MyThread extends Thread {
	NumberPrinter printer = new NumberPrinter();

	public void run() {
		printer.print();
	}
}
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 method synchronization only works if the instance method is locked by all threads. If the java threads are locks for different instances of class methods, then the synchronization will not work. All java threads should attempt to lock the same object method, and if the lock is not available, the thread will wait until the lock is released. This will ensure the sequence method access in the Java class. If threads lock different instance methods in the class, there will be no synchronization.



Synchronized Method Using static method

The java static method is a single instance of the method reference across class objects. The static keyword in the method will allow only one instance of the method reference to be created. If the synchronised method is configured as a static synchronised method, all threads will invoke the method from the same memory reference. If the synchronised java method is locked by a thread, other threads should wait until the lock is released.

package com.yawintutor;

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

public class MyThread extends Thread {
	NumberPrinter printer = new NumberPrinter();

	public void run() {
		printer.print();
	}
}

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


Synchronized Method Using static class object

The java thread will create a new class instance that interns will create a new java synchronised method instance. If a thread locks the synchronised java method, the other java method locks another java method instance. The synchronisation will therefore not work in the java threads. If the class is created as a static object, the java method in the class will have a single instance.

package com.yawintutor;

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

public class MyThread extends Thread {
	static NumberPrinter printer = new NumberPrinter();

	public void run() {
		printer.print();
	}
}

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


Synchronized Method Using single class instance

If a single instance of the class is used in threads, the lock will be generated on the same reference of the java method. Therefore, the synchronisation of the Java method will work. In this case , a single instance created in the java application framework can be used. The application framework will create and maintain a single class instance.

package com.yawintutor;

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

public class MyThread extends Thread {
	public NumberPrinter printer;

	public void run() {
		printer.print();
	}
}
package com.yawintutor;

public class MyThreadMain {
	public static void main(String[] args) throws Exception {
		NumberPrinter printer = new NumberPrinter();
		
		MyThread thread1 = new MyThread();
		thread1.setName("THREAD 1");
		thread1.printer = printer;
		thread1.start();

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

	}
}

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



Related Articles

Leave a Reply

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