Clean ⢠Professional
Synchronization is a core concept in Java multithreading that ensures controlled access to shared resources. It prevents multiple threads from interfering with each other when reading or modifying shared data, ensuring thread safety and data consistency.
Synchronization is a mechanism that coordinates thread execution in Java so that only one thread at a time can access a critical section of code that manipulates shared resources.
In multithreaded programs:
count++ are not atomic.Example:
Two threads increment a shared counter:
| Thread | Operation | Result (without sync) |
|---|---|---|
| A | count++ | reads 10, writes 11 |
| B | count++ | reads 10, writes 11 |
| Final | count | 11 (lost one increment) |
Without synchronization, the expected value is lost.

Process synchronization is a technique used to coordinate multiple processes (independent programs running on the OS) so they can share resources safely without conflicts.
Key Points:
Solution using a file lock (Java NIO example):
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
publicclassProcessSyncExample {
publicstaticvoidmain(String[] args)throws Exception {
try (RandomAccessFilefile=newRandomAccessFile("shared.txt","rw");
FileChannelchannel= file.getChannel()) {
// Try to acquire an exclusive lock on the file
try (FileLocklock= channel.lock()) {
System.out.println("File locked by process: " + Thread.currentThread().getId());
file.writeUTF("Writing safely to file by " + Thread.currentThread().getId());
Thread.sleep(2000);// simulate processing time
}// lock released automatically
}
}
}
ā Explanation:

FileLock ensures only one process at a time can write to the file.Thread synchronization is used to coordinate multiple threads within a single process (JVM) so that shared data is accessed safely.
Key Points:
synchronized keyword (methods or blocks)ReentrantLock, ReadWriteLock)AtomicInteger, AtomicLong)wait(), notify(), notifyAll() for thread communicationSolution using synchronized method:
classBankAccount {
privateintbalance=100;
publicsynchronizedvoidwithdraw(int amount) {
if (balance >= amount) {
System.out.println(Thread.currentThread().getName() +" is withdrawing " + amount);
balance -= amount;
System.out.println("New balance: " + balance);
}else {
System.out.println(Thread.currentThread().getName() +" insufficient balance");
}
}
publicintgetBalance() {
return balance;
}
}
publicclassThreadSyncExample {
publicstaticvoidmain(String[] args) {
BankAccountaccount=newBankAccount();
Runnabletask= () -> account.withdraw(50);
Threadt1=newThread(task,"Thread-1");
Threadt2=newThread(task,"Thread-2");
t1.start();
t2.start();
}
}
ā Explanation:

synchronized ensures only one thread can execute withdraw() at a time.| Feature | Process Synchronization | Thread Synchronization |
|---|---|---|
| Scope | Between processes | Between threads of the same process |
| Memory Space | Separate memory spaces | Shared memory space |
| Mechanism | OS-level (semaphores, mutex, file locks) | JVM-level / Language-level (synchronized, Locks, Atomic variables) |
| Overhead | High (context switching between processes) | Lower (threads share memory, lightweight) |
| Example | Two programs writing to the same file safely | Multiple threads updating a shared counter safely |
Java provides multiple mechanisms to ensure that shared resources are accessed safely in multithreaded programs:

1. Synchronized Methods
synchronized keyword ensures that only one thread at a time can execute that method for the same object.this) for instance methods or the Class object for static methods.Example:
classCounter {
privateintcount=0;
publicsynchronizedvoidincrement() {
count++;
}
}
2. Synchronized Blocks
this.Example:
classCounter {
privateintcount=0;
publicvoidincrement() {
synchronized (this) {// only this block is synchronized
count++;
}
}
}
3. Static Synchronization
Example:
classCounter {
privatestaticintcount=0;
publicstaticsynchronizedvoidincrement() {
count++;
}
}
4. Explicit Locks (ReentrantLock, ReadWriteLock)
synchronized keyword.Example with ReentrantLock:
import java.util.concurrent.locks.ReentrantLock;
classCounter {
privateintcount=0;
privateReentrantLocklock=newReentrantLock();
publicvoidincrement() {
lock.lock();
try {
count++;
}finally {
lock.unlock();
}
}
}
5. Atomic Classes (AtomicInteger, AtomicLong)
java.util.concurrent.atomic.incrementAndGet() are atomic, meaning they execute completely without interference from other threads.Example:
import java.util.concurrent.atomic.AtomicInteger;
classCounter {
privateAtomicIntegercount=newAtomicInteger(0);
publicvoidincrement() {
count.incrementAndGet();// atomic operation
}
}

This synchronizes the entire method, so only one thread can execute it on the same object at a time.
Syntax:
publicsynchronizedvoidincrement() {
count++;
}
Instead of locking the whole method, you can synchronize only a specific block of code inside the method.
Syntax:
publicvoidincrement() {
synchronized(this) {// Lock on the current object
count++;
}
}
this.Used for static methods or blocks to lock class-level resources rather than object-level resources.
Syntax:
publicstaticsynchronizedvoidstaticIncrement() {
staticCount++;
}
Or using a block:
synchronized(MyClass.class) {
staticCount++;
}
You can explicitly synchronize on any object, not necessarily this.
Syntax:
Objectlock=newObject();
publicvoidincrement() {
synchronized(lock) {
count++;
}
}
Java provides built-in synchronized versions of collections in java.util.Collections.
List<String> list = Collections.synchronizedList(newArrayList<>());
From Java 5 onward, you can use Lock interface for more flexible synchronization.
ReentrantLocklock=newReentrantLock();
lock.lock();
try {
count++;
}finally {
lock.unlock();
}
synchronized.| Type | Scope | Key Feature | Example |
|---|---|---|---|
| Method-level | Whole method | Locks the object | synchronized void method() |
| Block-level | Critical section | Locks part of method | synchronized(this) {} |
| Static | Class-level | Locks class | static synchronized void method() |
| Object-level | Specific object | Locks any object | synchronized(lockObject) {} |
| Synchronized collections | Collections | Thread-safe collections | Collections.synchronizedList() |
| Explicit Locks | Custom control | Advanced locking | ReentrantLock |
Example ā Synchronized Method:
classCounter {
privateintcount=0;
publicsynchronizedvoidincrement() {
count++;
}
publicsynchronizedintgetCount() {
return count;
}
}
Example ā Synchronized Block:
classCounter {
privateintcount=0;
publicvoidincrement() {
synchronized (this) {// critical section
count++;
}
}
}

Example:
// Object-level lock
Counterc1=newCounter();
Counterc2=newCounter();
c1.increment();// Thread locks only c1
c2.increment();// Thread locks only c2
// Class-level lock
Counter.incrementStatic();// Locks class, other threads must wait
Think of a single-lane bridge: