How many types of Locks are there in JAVA

Category : Java | Sub Category : Java Threads | By Prasad Bonam Last updated: 2023-08-16 02:49:43 Viewed : 397


In Java, there are several types of locks that are used for synchronization and concurrency control to ensure that multiple threads can access shared resources in a controlled and coordinated manner. Here are some of the common types of locks in Java:

  1. Synchronized Lock: The synchronized keyword is used to create intrinsic locks (also known as monitor locks) around critical sections of code. It provides mutual exclusion, allowing only one thread to execute the synchronized block of code at a time.

  2. ReentrantLock: The ReentrantLock class from the java.util.concurrent.locks package provides an explicit lock mechanism that allows more flexibility than synchronized blocks. It supports reentrant locking, meaning a thread that holds the lock can re-enter the synchronized block without deadlocking itself.

  3. ReadWriteLock: The ReadWriteLock interface from the java.util.concurrent.locks package provides separate locks for read and write operations. Multiple threads can hold the read lock simultaneously as long as no thread holds the write lock. This improves concurrency in scenarios where reads are more frequent than writes.

  4. StampedLock: The StampedLock class from the java.util.concurrent.locks package provides a more advanced lock mechanism that supports optimistic read locking. Its useful when you expect reads to be much more common than writes and you want to avoid blocking readers when writers are infrequent.

  5. LockSupport: The LockSupport class provides static methods for blocking and unblocking threads at the thread level. Its used for lower-level synchronization operations and is typically used to create custom synchronization constructs.

  6. Condition: The Condition interface, also from the java.util.concurrent.locks package, is used in conjunction with lock objects to allow threads to wait until a specific condition is met. Its often used for more advanced synchronization scenarios.

  7. Semaphore: The Semaphore class from the java.util.concurrent package is a synchronization primitive that allows a fixed number of permits to be acquired, which can help control access to a limited set of resources.

  8. CountDownLatch: The CountDownLatch class from the java.util.concurrent package is a synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

  9. CyclicBarrier: The CyclicBarrier class from the java.util.concurrent package allows a set of threads to wait at a barrier until all participating threads reach that point. Once all threads have reached the barrier, they are released simultaneously.

These are some of the common types of locks and synchronization mechanisms in Java. The choice of lock type depends on the specific concurrency scenario you are dealing with. Its important to understand the characteristics and usage patterns of each type to effectively manage thread synchronization and avoid issues like deadlocks and contention.

there are several types of locks and synchronization mechanisms that you can use to manage thread access to shared resources. Lets explore some of these locks with examples and outputs.

Example 1: Using synchronized Keyword (Intrinsic Lock)

java
public class Counter { private int value; public synchronized void increment() { value++; } public synchronized int getValue() { return value; } } public class CounterThread extends Thread { private Counter counter; public CounterThread(Counter counter) { this.counter = counter; } @Override public void run() { for (int i = 0; i < 1000; i++) { counter.increment(); } } } public class Main { public static void main(String[] args) throws InterruptedException { Counter counter = new Counter(); CounterThread thread1 = new CounterThread(counter); CounterThread thread2 = new CounterThread(counter); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("Final value: " + counter.getValue()); } }

Output:

yaml
Final value: 2000

In this example, the synchronized keyword is used to acquire and release the intrinsic lock (monitor) associated with the object on which the method is called. This ensures that only one thread can execute the synchronized method at a time, ensuring thread-safety.

Example 2: Using ReentrantLock

java
import java.util.concurrent.locks.*; public class ReentrantCounter { private int value; private Lock lock = new ReentrantLock(); public void increment() { lock.lock(); try { value++; } finally { lock.unlock(); } } public int getValue() { return value; } } public class ReentrantCounterThread extends Thread { private ReentrantCounter counter; public ReentrantCounterThread(ReentrantCounter counter) { this.counter = counter; } @Override public void run() { for (int i = 0; i < 1000; i++) { counter.increment(); } } } public class Main { public static void main(String[] args) throws InterruptedException { ReentrantCounter counter = new ReentrantCounter(); ReentrantCounterThread thread1 = new ReentrantCounterThread(counter); ReentrantCounterThread thread2 = new ReentrantCounterThread(counter); thread1.start(); thread2.start(); thread1.join(); thread2.join(); System.out.println("Final value: " + counter.getValue()); } }

Output:

yaml
Final value: 2000

In this example, ReentrantLock is used for explicit locking. It allows a thread to re-enter the same lock multiple times without getting deadlocked. The lock must be released the same number of times it was acquired.

These are just a couple of examples demonstrating different types of locks in Java. Other synchronization mechanisms like ReadWriteLock, Semaphore, and Condition can also be used based on specific concurrency requirements.

Search
Related Articles

Leave a Comment: