Synchronization and Deadlocks in Java Threads with Examples
#Synchronization Deadlocks in Java Threads with Examples
Introduction
In Java multithreading, multiple threads often access shared resources like variables, files, or databases. To avoid inconsistent data or race conditions, we use synchronization. However, improper synchronization can lead to a serious problem called deadlock.
This article explains synchronization and deadlocks in Java with practical examples.
Synchronization is a mechanism that ensures only one thread can access a shared resource at a time. It prevents race conditions and ensures data consistency.
Synchronized Methods – Lock applied on the object level.
Synchronized Blocks – Lock applied to a smaller section of code.
Static Synchronization – Lock applied on the class level.
class Table {
synchronized void printTable(int n) {
for (int i = 1; i <= 5; i++) {
System.out.println(n * i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class MyThread1 extends Thread {
Table t;
MyThread1(Table t) { this.t = t; }
public void run() { t.printTable(5); }
}
class MyThread2 extends Thread {
Table t;
MyThread2(Table t) { this.t = t; }
public void run() { t.printTable(100); }
}
public class SyncDemo {
public static void main(String[] args) {
Table obj = new Table();
MyThread1 t1 = new MyThread1(obj);
MyThread2 t2 = new MyThread2(obj);
t1.start();
t2.start();
}
}
5
10
15
20
25
100
200
300
400
500
(Execution order is controlled, preventing thread interference.)
A deadlock occurs when two or more threads wait indefinitely for each other to release resources, causing the program to freeze.
class Resource {
synchronized void method1(Resource r) {
System.out.println(Thread.currentThread().getName() + " is executing method1");
try { Thread.sleep(100); } catch (InterruptedException e) {}
r.method2(this);
}
synchronized void method2(Resource r) {
System.out.println(Thread.currentThread().getName() + " is executing method2");
try { Thread.sleep(100); } catch (InterruptedException e) {}
r.method1(this);
}
}
public class DeadlockDemo {
public static void main(String[] args) {
Resource r1 = new Resource();
Resource r2 = new Resource();
Thread t1 = new Thread(() -> r1.method1(r2), "Thread-1");
Thread t2 = new Thread(() -> r2.method1(r1), "Thread-2");
t1.start();
t2.start();
}
}
Here, Thread-1
waits for r2
and Thread-2
waits for r1
, causing a deadlock.
Acquire locks in a consistent order.
Use timeout locks (tryLock()
in ReentrantLock
).
Minimize synchronized code.
Use higher-level concurrency utilities (java.util.concurrent
).
Aspect | Synchronization | Deadlock |
---|---|---|
Purpose | To control thread access to resources | Occurs due to improper lock handling |
Outcome | Prevents race conditions | Freezes program execution |
Example Use | Banking transactions, ticket booking | Circular waiting between two resources |
Synchronization is essential for thread safety in Java.
Deadlocks are a common risk when using synchronization incorrectly.
Following best practices ensures smooth and efficient multithreaded execution.
SEO Keywords to Target:
Java synchronization
Deadlocks in Java threads
Synchronized methods and blocks
Avoid deadlocks in Java
Java multithreading examples