Java Locks & Semaphores
In this page:
ReentrantLock Basics
ReentrantLock is a more flexible, explicit alternative to the synchronized keyword. You must call lock() to acquire it and unlock() inside a finally block to release it, since unlike synchronized blocks, the JVM won't release a ReentrantLock for you automatically if an exception is thrown.
Example: ReentrantLock Basics
import java.util.concurrent.locks.ReentrantLock;
public class Main {
static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
lock.lock();
try {
System.out.println("Critical section");
} finally {
lock.unlock(); // must release manually, unlike synchronized
}
}
}
Login to try C/C++/Java/PHP code in the editor
Non-Blocking Locks with tryLock()
tryLock() attempts to acquire a lock without blocking the calling thread -- it returns true immediately if the lock was free, or false right away if it wasn't, letting a thread decide to do something else instead of waiting indefinitely for a busy resource.
Example: Non-Blocking Locks with tryLock()
import java.util.concurrent.locks.ReentrantLock;
public class Main {
static final ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
if (lock.tryLock()) { // returns immediately instead of blocking
try { System.out.println("Acquired the lock"); } finally { lock.unlock(); }
} else {
System.out.println("Lock was busy, doing something else");
}
}
}
Login to try C/C++/Java/PHP code in the editor
ReadWriteLock
ReadWriteLock improves throughput by allowing any number of threads to read a shared resource simultaneously, while still guaranteeing that only one thread can hold the write lock at a time and that writes are exclusive of all reads -- ideal for data that's read far more often than it's modified.
Example: ReadWriteLock
import java.util.concurrent.locks.*;
public class Main {
static final ReadWriteLock rwLock = new ReentrantReadWriteLock();
public static void main(String[] args) {
rwLock.readLock().lock(); // multiple readers allowed at once
try { System.out.println("Reading"); } finally { rwLock.readLock().unlock(); }
rwLock.writeLock().lock(); // exclusive of all reads and other writes
try { System.out.println("Writing"); } finally { rwLock.writeLock().unlock(); }
}
}
Login to try C/C++/Java/PHP code in the editor
Semaphore Basics
A Semaphore controls access to a limited pool of a resource using permits: threads call acquire() to take a permit before proceeding and release() to give it back afterward, which is the standard way to cap how many threads can use something concurrently, like a fixed-size connection pool.
Example: Semaphore Basics
import java.util.concurrent.Semaphore;
public class Main {
public static void main(String[] args) throws InterruptedException {
Semaphore semaphore = new Semaphore(2); // 2 permits, like a connection pool of size 2
semaphore.acquire();
System.out.println("Permit acquired, available: " + semaphore.availablePermits());
semaphore.release();
}
}
Login to try C/C++/Java/PHP code in the editor
Fair Lock Queueing
By default, Java locks make no guarantee about the order in which waiting threads acquire a contested lock. Enabling fairness in a ReentrantLock's constructor forces the lock to grant access to whichever thread has been waiting longest, at some cost to raw throughput.
Example: Fair Lock Queueing
import java.util.concurrent.locks.ReentrantLock;
public class Main {
public static void main(String[] args) {
ReentrantLock fairLock = new ReentrantLock(true); // grants access in waiting order
fairLock.lock();
try { System.out.println("Longest-waiting thread goes first"); } finally { fairLock.unlock(); }
}
}
Login to try C/C++/Java/PHP code in the editor
Chapter Quiz — Complete all 19 topics to unlock
0/19 topics done
Complete these topics first:
- Java Reflection API
- Java Annotations Advanced
- Java Garbage Collection
- Java Memory Management
- Java Performance Optimization
- Java Advanced Interview Questions
- Java CompletableFuture
- Java Atomic Classes
- Java Locks & Semaphores
- Java Concurrent Collections
- Java Cryptography Basics
- Java Hashing (MD5, SHA)
- Java SSL & HTTPS
- Java Logging (Log4j/SLF4J)
- Java Serialization Advanced
- Java Interview Questions Advanced
- Java Connection Pooling
- Java Test Driven Development
- Java Integration Testing