Java Synchronized Keyword Example
In this example, we shall show you how to use the Java synchronized keyword and achieve synchronization in java.
1. What is Synchronized Keyword in Java?
Java allows us to use concurrency and multithreading pretty easily. Some of the most common use cases are those in which we have an object and many threads interacting with it. This can create many problems, because in cases that 2 different threads try to interact with the same resource, we have no idea what may actually happen (which is something that needs to be avoided in programming).
This is why Java provides the synchronized
keyword, which allows us to handle certain parts of code in an atomic
way. Essentially, this means that when there are more than one threads that need to access a synchronized
part of code, (increment a counter, add objects in a list, etc) there is no way that one thread will interrupt another thread, so we are perfectly sure that everything will work as intended.
2. How to use the Java Synchronized Keyword
There are two ways to use the synchronized
keyword to achieve synchronization in java. It can either be set in a method of a class, or in part of code inside a method, which becomes a synchronized
block. In both cases, code inside a synchronized
method or block is only accessed by one thread at a time.
Below, we present you both ways to use the synchronized
keyword.
2.1 Synchronized Method
The SynchronizedMethodClass.java
class below has one method, syncMethod(String threadName)
, stated with the synchronized
keyword.
SynchronizedMethodClass.java
import java.util.ArrayList;
public class SynchronizedMethodClass {
private ArrayList<Integer> nums1;
private String pos1;
public SynchronizedMethodClass() {
nums1 = new ArrayList<Integer>();
nums1.add(0);
pos1 = "0";
}
public ArrayList<Integer> getNums1() {
return nums1;
}
public void setNums1(ArrayList<Integer> nums1) {
this.nums1 = nums1;
}
public String getPos1() {
return pos1;
}
public void setPos1(String pos1) {
this.pos1 = pos1;
}
public synchronized void syncMethod(String threadName) {
Integer number = nums1.get(nums1.size() - 1) + 1;
pos1 = String.valueOf(number);
nums1.add(number);
System.out.println("Thread " + threadName + " : "
+ nums1.get(nums1.size() - 1) + " - " + pos1);
}
}
The SyncMethodRunnable.java
class below is an implementation of the Runnable interface that will invoke the synchronized
method of its SynchronizedMethodClass
field, when started.
SyncMethodRunnable.java
public class SyncMethodRunnable implements Runnable {
private SynchronizedMethodClass synchronizedMethodClass;
private String threadName;
public SyncMethodRunnable(SynchronizedMethodClass synchronizedMethodClass, String threadName) {
this.synchronizedMethodClass = synchronizedMethodClass;
this.threadName = threadName;
}
public void run() {
for (int i = 0; i < 5; i++) {
synchronizedMethodClass.syncMethod(threadName);
}
}
}
In order to run the example, we create two Threads to run two instances of the SyncMethodRunnable
. Both threads use the same instance of the SynchronizedMethodClass
class. So both threads will invoke the synchronized
method of the SynchronizedMethodClass
object.
we do it AppForSynchronizedMethod.java
class.
AppForSynchronizedMethod.java
public class AppForSynchronizedMethod {
public static void main(String[] args) throws InterruptedException {
SynchronizedMethodClass example1 = new SynchronizedMethodClass();
System.out.println("**** Running AppForSynchronizedMethod.java *****");
System.out.println("**** Synchronized Method example*****");
Thread thread1 = new Thread(new SyncMethodRunnable(example1, "1"));
Thread thread2 = new Thread(new SyncMethodRunnable(example1, "2"));
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("List 1 is: " + example1.getNums1()
+ " /Position 1: " + example1.getPos1()
+ "\n");
}
}
As a result, both threads start, but the first one to invoke the synchronized
method of the SynchronizedMethodClass
object is Thread 1, and when it finishes Thread 2 manages to invoke the method. Since they both use the same instance of the SynchronizedMethodClass
class, the list is finally filled with 10 numbers and the position is set to 10.
Output of AppForSynchronizedMethod.java
class is shown in Fig. 1 below.
2.2 Synchronized Block
The SynchronizedBlockClass.java
class below has one method, inside which the synchronized
keyword is set. The synchronized
block created takes a parameter, which is the instance of the SynchronizedBlockClass.java
class. This parameter may be one attribute of the class, or the whole class object, according to the needs of the programmer. Since the whole instance of the class is set as the parameter in the synchronized
block, it is now locked against changes until the thread finishes code execution in the block. The rest part of the method that is not inside the block may be accessed simultaneously by all threads that invoke the method.
SynchronizedBlockClass.java
import java.util.ArrayList;
public class SynchronizedBlockClass {
private ArrayList<Integer> nums2;
private String pos2;
private int counter;
public SynchronizedBlockClass() {
nums2 = new ArrayList<Integer>();
nums2.add(0);
pos2 = "0";
}
public ArrayList<Integer> getNums2() {
return nums2;
}
public void setNums2(ArrayList<Integer> nums2) {
this.nums2 = nums2;
}
public String getPos2() {
return pos2;
}
public void setPos2(String pos2) {
this.pos2 = pos2;
}
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
public void syncBlock(String threadName) {
counter++;
System.out.println("Thread " + threadName + " - counter: " + counter);
synchronized (this) {
Integer number = nums2.get(nums2.size() - 1) + 1;
pos2 = String.valueOf(number);
nums2.add(number);
System.out.println("Thread " + threadName + " Added to list: "
+ nums2.get(nums2.size() - 1) + " - " + pos2);
}
}
}
The SyncBlockRunnable.java
class below is an implementation of the Runnable interface that will invoke the synchronized
method of its SynchronizedBlockClass
field, when started.
SynchronizedBlockRunnabled.java
public class SyncBlockRunnable implements Runnable {
private SynchronizedBlockClass synchronizedBlockClass;
private String threadName;
public SyncBlockRunnable(SynchronizedBlockClass synchronizedBlockClass, String threadName) {
this.synchronizedBlockClass = synchronizedBlockClass;
this.threadName = threadName;
}
public void run() {
for (int i = 0; i < 5; i++) {
synchronizedBlockClass.syncBlock(threadName);
}
}
}
Now in AppForSynchronizedBlock.java
class, we create two Threads to run two instances of the SyncBlockRunnable
. Both threads use the same instance of the SynchronizedBlockClass
class. So both threads will invoke its method, but only one of them will get in the synchronized
block of the method at a time.
AppForSynchronizedBlock.java
public class AppForSynchronizedBlock {
public static void main(String[] args) throws InterruptedException {
SynchronizedBlockClass example2 = new SynchronizedBlockClass();
System.out.println("**** Running AppForSynchronizedBlock.java *****");
System.out.println("**** Synchronized Block example*****");
Thread syncMethodThread1 = new Thread(new SyncBlockRunnable(example2, "1"));
Thread syncMethodThread2 = new Thread(new SyncBlockRunnable(example2, "2"));
syncMethodThread1.start();
syncMethodThread2.start();
syncMethodThread1.join();
syncMethodThread2.join();
System.out.println("List 2 is: " + example2.getNums2()
+ " /Position 2: " + example2.getPos2()
+ " / counter : " + example2.getCounter());
}
}
As a result, both threads invoke the method of the SynchronizedBlockClass
object. But only one thread at a time locks the object to run the synchronized
block. The counter
increment is out of the synchronized
block, so the counter
result is wrong. But the rest of the method that is inside the synchronized
block is protected against being invoked by many threads simultaneously and achieve synchronization in java, so the list
and position
result is correct.
Output of AppForSynchronizedBlock.java
class is shown in Fig. 2 below.
3. Download the Source Code
You can download the full source code of
synchronized
example here : Java Synchronized Keyword ExampleLast updated on Aug 23, 2019