Synchronization in Java is a mechanism that ensures that only one
thread can access a shared resource (like a variable, method, or block
of code) at a time.
It helps prevent data loss & deadlock
Why Synchronization Is Needed
When multiple threads access shared data concurrently, they may produce
inconsistent results.
Example:
If two threads try to update the same variable at the same time, one update might
be lost.
🔹 Types of Synchronization in Java
1. Synchronized Method
2. Synchronized Block
3. Static Synchronization (class-level lock)
4. Inter-thread Communication (using wait(), notify(), notifyAll())
1. Multithreading wihout Synchronization :
class Note extends Thread{
public void run() {
for (int i = 1; i <= 5; i++)
{
[Link]("Note: "+i);
}
}
}
class Book extends Thread {
public void run() {
for (int i = 1; i <= 5; i++)
{
[Link]("Book: "+i);
}
}
}
public class Main {
public static void main(String args[]) {
Note t1 = new Note();
Book t2 = new Book();
[Link]();
[Link]();
}
}
2. Multithreading wih Synchronization :
Synchronized public void run() {
for (int i = 1; i <= 5; i++)
{
[Link]("Note: "+i);
}
}
3. Synchronized Block
Instead of synchronizing the entire method, you can synchronize only part
of it.
Useful when only a few statements need synchronization.
void printTable(int n) {
synchronized(this) { // synchronized block
for (int i = 1; i <= 5; i++) {
[Link](n * i);
try {
[Link](500);
} catch (InterruptedException e) {
[Link](e);
}
}
}
}
4. Static Synchronization
Used to synchronize static methods — the lock is on the class object, not
the instance.
synchronized static void printTable(int n)
{
}
5. Inter-thread Communication
Used for cooperation between threads using methods of Object class:
wait() — tells thread to wait until another thread calls notify()
notify() — wakes up one waiting thread
notifyAll() — wakes up all waiting threads
class Bank {
int balance = 1000;
synchronized void withdraw(int amount) {
[Link]("Attempting to withdraw " + amount + "...");
if (balance < amount) {
[Link]("Insufficient balance! Waiting for deposit...");
try {
wait(); // waits until someone deposits money
} catch (InterruptedException e) {
[Link](e);
balance -= amount;
[Link]("Withdrawal successful! Remaining balance: " +
balance);
}
synchronized void deposit(int amount) {
[Link]("Depositing " + amount + "...");
balance += amount;
[Link]("Deposit successful! New balance: " + balance);
notify(); // wakes up the waiting thread
class Customer1 extends Thread {
Bank b;
Customer1(Bank b) {
this.b = b;
public void run() {
[Link](1500);
class Customer2 extends Thread {
Bank b;
Customer2(Bank b) {
this.b = b;
public void run() {
[Link](1000);
public class Main {
public static void main(String args[]) {
Bank b = new Bank();
Customer1 t1 = new Customer1(b);
Customer2 t2 = new Customer2(b);
[Link]();
try {
[Link](1000); // ensure withdraw happens first
} catch (Exception e) {}
[Link]();
}
Important Points
Every object in Java has an intrinsic lock (monitor lock).
The thread must acquire the lock before entering a synchronized block
or method.
Synchronization can cause performance issues if overused.
Use [Link] (like ReentrantLock) for more
flexibility.
🔹 Advantages
✅ Prevents data inconsistency
✅ Ensures thread safety
🔹 Disadvantages
❌ Decreases performance due to locking overhead
❌ May lead to deadlocks if not used carefully
Thread Priority
Each thread has a priority value (1 to 10).
MIN_PRIORITY = 1 (lowest)
NORM_PRIORITY = 5 (default)
MAX_PRIORITY = 10 (highest)
Thread priority acts as a hint to the thread scheduler — it may give
more CPU time to higher-priority threads, but output order is not
guaranteed (depends on OS and JVM).
[Link]() → returns a reference to the currently
running thread.
.getName() → returns the name of the thread.
.getPriority() → returns the priority value (1 to 10).
You can set them using .setName() and .setPriority().
public class Main {
public static void main(String[] args) {
// Get the reference to the current (main) thread
Thread t = [Link]();
// Display main thread name and priority
[Link]("Current Thread Name: " + [Link]());
[Link]("Current Thread Priority: " + [Link]());
// Change thread name and priority
[Link]("MyMainThread");
[Link](Thread.MAX_PRIORITY); // 10
// Display updated details
[Link]("After changing...");
[Link]("Updated Thread Name: " + [Link]());
[Link]("Updated Thread Priority: " + [Link]());
}
What is a Daemon Thread?
A Daemon Thread in Java is a background thread that runs to support other
threads (like garbage collection or background tasks).
It automatically ends when all user threads have finished.
Simple Daemon Thread Example
class Demo extends Thread {
public void run() {
if ([Link]().isDaemon()) {
[Link]("This is a Daemon
thread");
} else {
[Link]("This is a User
thread");
}
}
}
public class Main {
public static void main(String[] args) {
Demo t1 = new Demo();
Demo t2 = new Demo();
[Link](true); // make t1 a daemon thread
[Link]();
[Link]();
}
}
Output:
This is a Daemon thread
This is a User thread
(Order may change depending on the CPU scheduler.)
Key Points:
Daemon threads run in the background.
Must call setDaemon(true) before calling start().
JVM exits when all user threads finish, even if daemon threads are still
running.
*******************************************