Explain Codes LogoExplain Codes Logo

What does 'synchronized' mean?

java
synchronized
thread-safety
java-memory-model
Anton ShumikhinbyAnton Shumikhin·Aug 3, 2024
TLDR

In Java, the synchronized keyword guarantees that a single thread can exclusively access a method or a block of code at any given time. It effectively creates a lock on the object, blocking other threads from entering any synchronized sections tied to it until the current thread releases the lock.

public class Wallet { private int balance = 0; public synchronized void deposit(int funds) { balance += funds; } public synchronized int checkBalance() { return balance; } }

In the snippet above, the deposit() and checkBalance() methods are synchronized. While one thread executes deposit(), other threads can't simultaneously invoke deposit or checkBalance tied to the same Wallet instance, protecting the data integrity.

Digging deeper: Uncovering the depths of 'synchronized'

The role of 'synchronized' in atomic access

Consider the synchronized keyword your guard dog against unwanted thread competition. It stands as your gatekeeper allowing only one thread at a time to pass while others must wait their turn, enforcing atomic access and maintaining state consistency.

Static method synchronization: One for all, all for one

Synchronization also extends to static methods. In this case, the method locks on the entire class's monitor, not just an individual instance:

public class GlobalCounter { private static int count = 0; public static synchronized void increment() { count++; // Here, // we're going up, one by one! } // Get in line, threads! }

The performance trade-off: Don't go overboard

Although synchronized helps maintain thread safety, overdoing it can lead to performance degradation due to thread contention. It’s a fine line to tread between ensuring safety and maintaining efficiency.

Beyond methods: Block-level synchronization

The use of synchronized extends beyond methods and can be used within code blocks. This method provides granular control over which part of your code should be thread-safe.

public void transferFunds(Wallet targetWallet, int amount) { synchronized (this) { if (balance >= amount) { balance -= amount; synchronized (targetWallet) { targetWallet.deposit(amount); } } } // Block complete. Next customer, please! }

In the code above, funds are transferred atomically by concurrently locking both Wallet instances.

Right tool for the job: Alternatives to 'synchronized'

synchronized isn’t the answer to all concurrency problems. Non-locking collections such as ArrayList or ConcurrentHashMap can offer significant performance improvements when fine-grained synchronization isn't required.

Adding visibility to synchronized

When a variable is accessed inside a synchronized block, it guarantees visibility, meaning the most recent update by any thread to that variable will be reflected.

Getting familiar with the Java Memory Model (JMM)

In order to make the most efficient use of synchronized, it's essential to understand how Java Memory Model (JMM) works. It ensures that changes made by one thread becomes visible to all other threads, thereby maintaining a safe happens-before relationship.