Java Keyword synchronized
synchronized keyword in java
In Java programming, the synchronized keyword plays a critical role in managing concurrent access to shared resources, ensuring thread safety and preventing data races.
What is the synchronized Keyword?
Concurrency in Java allows multiple threads to execute simultaneously, which can lead to issues when multiple threads access shared data concurrently. The synchronized keyword helps in controlling access to critical sections of code or shared resources by allowing only one thread at a time to execute a synchronized block of code or method on the same object.
Usage of synchronized
The synchronized keyword can be used in two ways:
- Synchronized Methods: Applying synchronized to entire methods ensures that only one thread can execute the method at any given time.
- Synchronized Blocks: Using synchronized blocks allows for more fine-grained control over which part of the code is synchronized, improving performance by reducing the scope of synchronization.
Example: Using synchronized in Java
Let's consider an example where multiple threads access and modify a shared counter without synchronization, leading to incorrect results. Then, we'll modify the code to use synchronized to ensure correct behavior.
public class SynchronizedExample {
private static int counter = 0;
// Method to increment the counter without synchronization
private static void incrementCounter() {
for (int i = 0; i < 10000; i++) {
counter++;
}
}
public static void main(String[] args) throws InterruptedException {
// Create multiple threads to increment the counter concurrently
Thread thread1 = new Thread(() -> {
incrementCounter();
});
Thread thread2 = new Thread(() -> {
incrementCounter();
});
// Start threads
thread1.start();
thread2.start();
// Wait for threads to complete
thread1.join();
thread2.join();
// Display the final value of the counter
System.out.println("Without synchronization, Counter value: " + counter);
}
}
Output without synchronization::
Without synchronization, Counter value: 17092
In the above example, the expected final value of the counter should be 20000, but due to concurrent access without synchronization, the results are inconsistent.
Now, let's modify the incrementCounter method to use synchronized to ensure thread safety:
// Method to increment the counter with synchronization
private static synchronized void incrementCounter() {
for (int i = 0; i < 10000; i++) {
counter++;
}
}
Output with synchronization::
With synchronization, Counter value: 20000
With the synchronized keyword applied to the incrementCounter method, only one thread can execute the method at a time, ensuring that all operations on counter are atomic and preventing data corruption.
When to Use synchronized
Use the synchronized keyword whenever you have shared data that is accessed and modified by multiple threads concurrently. It ensures thread safety by preventing race conditions and maintaining data integrity.