You are on page 1of 15

Synchronization in java

In this post, we will learn synchronization in java, and why we need Java
synchronization, how to write synchronized code and more important points
about synchronization.

Here is the table content of the article will we will cover this topic.
1. Synchronization in java?
2. Why do we use Synchronization in Java?
3. Locks in Java?
4. Types of Synchronization?
5. Multi-threading without Synchronization?
6. Multi-threading with Synchronization?
7. Important points about java synchronized?
8. Java synchronized block
i) synchronized block in non-static method
ii) synchronized block in static method
9. Java synchronized method
i) Java synchronization with non-static method
ii) Java synchronized method

Synchronization in java

In a multithreading environment, multiple threads can try to access the same


resources and can produce erroneous and unforeseen results. Java provides
a way to control the access of multiple threads to any shared resource.
Synchronization in java is a process where we want to allow only one thread
to access the shared resource at a time. So that multiple threads can work
together without creating any problems. The synchronization process can
achieve by synchronized keyword in java. The Synchronization keyword
makes the code thread-safe.
Why do we use Synchronization in Java?

Suppose you have two resources and there may be a chance when multiple
threads try to attempt the same resource and produce errors. So
synchronization is used to handle the following errors:

1. Thread Interference Error: The thread interference error occurs when we


have more than one thread and they are running simultaneously. Because
they want to access the same piece of data and perform different operations
on the same data. The operation of one thread could overlap with another
thread and leads to data inconsistency.

2. Memory Consistency Error: The memory Consistency Error occurs


when the changes made by one thread may not be visible to the other
threads. The other threads have inconsistent views of the same shared data.

Locks in Java

Before moving further in synchronization, we have to understand the


concept of lock or monitor. In java, Each and every object has a lock
associated with it. When multiple threads access the shared resource, they
use the lock. A thread requests a lock to an object and access data from the
object meanwhile all other thread waits to release the lock. A thread releases
the lock after the completion of work.

Types of Synchronization
There are 2 types of synchronization in java as shown below:

1. Process Synchronization: The simultaneous execution of multiple threads


or processes to reach a state such that they commit to a certain sequence of
actions.

2. Thread Synchronization: Thread Synchronization allows to access the


shared space only one thread at a time.

In this post, we will discuss thread synchronization. The thread


synchronization is divided into two parts.

1. Mutual Exclusive: Mutual exclusion is the simplest type of thread


synchronization. This synchronization allows only one thread can execute the
shared resource at a time. When a thread accesses the shared resource, it
takes a lock and all other threads wait to release the lock. Let’s read how we
can achieve it. There are two ways
1. Synchronized method.
2. Synchronized block.

2. Cooperation (Inter-thread communication in java): Interthread


communication in java is used to avoid polling and is important when you
want to develop an application where two or more threads exchange some
information. Java provides three methods that are used for inter-thread
communication. Those methods are, wait(), notify() and notifyAll() and these
methods belong to the object class.

Multi-threading without Synchronization

Let’s discuss an example that prints the count by two different threads.

class Count
{
void printTable(int n)
{
//method not synchronized
for(int i=1;i<=5;i++)
{
System.out.println(n*i);
try
{
Thread.sleep(400);
}
catch(Exception e){System.out.println(e);}
}
}
}
class MyThread1 extends Thread
{
Count c;
MyThread1(Count c)
{
this.c=c;
}
public void run()
{
c.printTable(5);
}
}
class MyThread2 extends Thread
{
Count c;
MyThread2(Count c)
{
this.c=c;
}
public void run()
{
c.printTable(100);
}
}
public class WithoutSynchronization
{
public static void main(String args[])
{
Count obj = new Count();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}

Output: 5
100
200
10
15
300
400
20
500
25

Multi-threading with Synchronization


class Count

synchronized void printTable(int n)

{
//method not synchronized

for(int i=1;i<=5;i++)

System.out.println(n*i);

try

Thread.sleep(400);

catch(Exception e){System.out.println(e);}

class MyThread1 extends Thread

Count c;
MyThread1(Count c)
{
this.c=c;
}
public void run()
{
c.printTable(5);
}
}
class MyThread2 extends Thread
{
Count c;
MyThread2(Count c)
{
this.c=c;
}
public void run()
{
c.printTable(100);
}
}
public class WithSynchronization
{
public static void main(String args[])
{
Count obj = new Count();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}

Output: 5
10
15
20
25
100
200
300
400
500

Important points about java synchronized

1. Synchronized keyword in Java is used to synchronize the shared


resource when multiple threads use it. Synchronization in Java is used to
remove thread interference and memory inconstancy.

2. Java allows us to use the synchronized keyword with a method or block.

3. The concept of synchronization works based on lock. Whenever a thread


enters into a java synchronized method or blocks it acquires a lock and
releases the lock after completion of execution.

4. When a thread enters into a non-static synchronized method, it acquires


an object-level lock. But when the thread enters into a static synchronized
java method it acquires a class-level lock.

5. when a java synchronized method calls another synchronized method then


it requires the same lock. But the current thread can enter without a lock
because it already holding the lock.

6. Synchronized block throws NullPointerEception, if the object used in the


java synchronized block is null.

7. A synchronized method is slow and can degrade performance because


threads have to wait for their turn.
8. It is always better to use the Java synchronized block instead of the
synchronized method because the using synchronized block only locks
critical section of code and avoid locking the whole method.

9. The static synchronized and non-static synchronized method can run


simultaneously because they lock on different objects.

Java synchronized method

We have read synchronization in java and Java block synchronization.


Multiple threads used the shared resources and access the fields and objects
reference fields. But it can create a problem with data inconsistency or
thread interference. We prevent these errors by use of synchronized
keyword in java. Let’s read the Java synchronized method.

To achieve the synchronization in java we can use the java synchronized


keyword with the method. A synchronized method is used to ensure that
only one thread can execute it at a time. As we discussed each object has a
lock or monitor, so when any thread accesses it, the thread performs certain
operations:

1. A thread checks the lock of the synchronized method. If there no other


thread is executing it then the lock will be available.

2. If the lock is available, the thread takes the lock and performs the operation
as per requirements. Meanwhile, all the other thread waits for the lock.

3. Multiple threads can’t take a lock at the same time.

The synchronized keyword can be used with a static method and a


non-static method(instance methods). Here we will see the static and
non-static synchronized method in java.

1. Java synchronization with non-static method

A synchronized non-static method is synchronized on the object level. If the


method is non-static, the lock is acquired on the current object. Each object
has its synchronized methods and only one thread per object can execute
inside a synchronized method. It is also known as object-level locking.
Syntax of synchronized Method

access_modifiers synchronized return_type method_name(method_parameters)

// method_code

Let’s see thread synchronization in java simple example

class Test
{
synchronized public void count()
{
for (int i = 0; i < 3; i++)
{
System.out.println(i);
try
{
Thread.sleep(400);
}
catch (Exception e)
{
System.out.println(e);
}
}
}
}
class MyThread extends Thread {
Test test;
MyThread (Test test) {
this.test = test;
}
@Override
public void run() {
test.count();
}
}
public class SynchronizedMethod
{
public static void main(String[] args)
{
Test obj = new Test(); //Object of Apple class that is shared amoung threads
MyThread thread1 = new MyThread(obj);
MyThread thread2 = new MyThread(obj);
thread1.start();
thread2.start();
}
}

Output: 0
1
2
0
1
2

In the above example, we are creating two threads thread1 and thread2. Both
are using the synchronized count() method. As it is synchronized, both are
using it one by one. Firstly, thread1 enters the count() method and gets a
lock meanwhile thread2 waits until thread1 finishes the execution. and
release the lock. After that thread2 gets the lock and completes the execution.

2. Java synchronized static method

As we know static methods belong to a class instead of an object. When we


use a synchronized keyword with a static method, the lock is acquired in the
class. In synchronized static methods only one thread can execute inside a
static synchronized method in the same class. If we have more than one static
synchronized method, then only one thread can execute any of these methods
at the same time.
Suppose we have two static synchronized methods, method1 and method2,
and two threads thread1 and thread2. Here thread1 or thread2 can execute
only one static method.

Syntax of static synchronized Method

access_modifiers synchronized static return_type method_name(method_parameters)

{
// method_code
}
class Test
{
synchronized static public void countIncrement()
{
System.out.println("Increment values");
for (int i = 0; i < 3; i++)
{
System.out.println(i);

try

Thread.sleep(400);

catch (Exception e)
{

System.out.println(e);
}
}
}
synchronized static public void countDecrement()
{
System.out.println("Decrement values");
for (int i = 3; i > 0; i--)
{
System.out.println(i);
try
{

Thread.sleep(400);

catch (Exception e)

{
System.out.println(e);
}
}
}
}
class MyThread extends Thread {
Test test;
MyThread (Test test) {
this.test = test;
}
@Override
public void run() {
test.countIncrement();
test.countDecrement();
}
}
public class SynchronizedMethod
{
public static void main(String[] args)
{
Test obj = new Test(); //Object of Apple class that is shared amoung threads

MyThread thread1 = new MyThread(obj);

MyThread thread2 = new MyThread(obj);

thread1.start();

thread2.start();

Output: Increment values


0
1
2
Increment values
0
1
2
Decrement values
3
2
1
Decrement values
3
2
1

In the above example, we have two static synchronized methods


(countIncrement() method and countDecrement() method) and two
threads(thread1 and thread2). One thread can access only one static method
at a time.

Java synchronized block

We have read synchronization in java and method synchronization with


synchronized keyword. In method synchronization, we synchronized the
whole code of the method. But sometimes we want to synchronize a portion of
a method, not the whole method. For such types of situations, we should use
Java synchronized block. In this post, we will read it in detail.

The Java synchronized block is used to synchronize a portion of code or set


of statements. Like the synchronized method, synchronized blocks in Java
are marked with the synchronized keyword. A synchronized block can be
executed by only one thread at a time and all other threads wait for the
completion of execution.

synchronized ( lockObject)
{
//synchronized statements
}

A thread can execute the synchronized block only to acquire the lock on
lockObject. Only one thread can acquire the monitor of a lock object at a time
meanwhile all other threads wait for the lock.

We can have two types of synchronized blocks.


1. synchronized block in non-static method

When you want to synchronize a portion of the method instead of the whole
method. We can use a synchronized block of Java code inside an
unsynchronized Java method.

access_modifiers return_type method_name(method_parameters)


{
synchronized (objLock)
{
// block of code
}
// method_code
}

You must think about why the synchronized block construct takes an object in
parentheses. This object is known as the monitor object. Only one thread can
execute inside a Java code block synchronized on the same monitor object.

class Test
{
public void countIncrement()
{
synchronized(this)
{
for (int i = 0; i < 3; i++)
{
System.out.println(i);
try
{
Thread.sleep(400);
}
catch (Exception e)
{
System.out.println(e);
}
}
}
}
}
class MyThread extends Thread {
Test test;
MyThread (Test test) {
this.test = test;
}
@Override
public void run() {
test.countIncrement();
}
}
public class SynchronizedMethod
{
public static void main(String[] args)
{

Test obj = new Test();

MyThread thread1 = new MyThread(obj);


MyThread thread2 = new MyThread(obj);

thread1.start();

thread2.start();

Output: 0
1
2
0
1
2

2. synchronized block in static method

We can use the Synchronized blocks inside the static method. Suppose if
we have two static methods with a synchronized block then only one
thread can execute inside any of these two methods at the same time.

class Test
{
synchronized static public void countIncrement()
{
synchronized (Test.class)
{
System.out.println("Increment values");
for (int i = 0; i < 3; i++)
{
System.out.println(i);
try
{
Thread.sleep(400);
}
catch (Exception e)

System.out.println(e);
}
}
}
}
synchronized static public void countDecrement()
{
synchronized (Test.class)
{
System.out.println("Decrement values");
for (int i = 3; i > 0; i--)
{
System.out.println(i);
try
{
Thread.sleep(400);
}
catch (Exception e)
{
System.out.println(e);
}
}

class MyThread extends Thread {

Test test;

MyThread (Test test) {

this.test = test;

@Override

public void run() {

test.countIncrement();

test.countDecrement();

public class SynchronizedMethod

public static void main(String[] args)

Test obj = new Test(); //Object of Apple class that is shared amoung threads

MyThread thread1 = new MyThread(obj);

MyThread thread2 = new MyThread(obj);

thread1.start();
thread2.start();

Output: Increment values


0
1
2
Increment values
0
1
2
Decrement values
3
2
1
Decrement values
3
2
1

You might also like