Use StampedLock to achieve efficient reading and writing
1. What is it?
StampedLock
It is a high-performance lock introduced by Java 8, providing three lock modes: write lock, pessimistic read lock and optimistic read lock.
With traditionalReentrantReadWriteLock
compared to,StampedLock
Pay more attention to performance, especially suitable for scenarios where more reads, less writes.
- Write lock: Blocks all other operations (similar to exclusive locks).
- Pessimistic reading lock: Shared lock, allowing multiple threads to read, but blocks write operations.
- Optimistic reading lock: A non-blocking read operation that allows concurrent write operations and verify data consistency if necessary.
2. What is its usage scenario?
-
Read more and write less scenarios: Such as cache, configuration data reading and other scenarios,
StampedLock
Optimistic read locks can significantly improve performance. - Scenarios that require quick read lock verification: In the case of optimistic reading, the consistency of the data can be verified and downgraded to pessimistic reading locks if necessary.
- Scenarios where write locks need to be processed first: Avoid the problem of long-term hunger caused by read operations in traditional read and write locks.
3. What APIs does it have?
Core API
Method name | describe |
---|---|
writeLock() |
Get the write lock and return a stamp (lock flag). |
readLock() |
Get the pessimistic read lock and return a stamp (lock flag). |
tryOptimisticRead() |
Gets optimistic read locks, returns a stamp, non-blocking, suitable for fast reads. |
unlockWrite(long stamp) |
Release the write lock and need to pass in the stamp returned when acquiring the lock. |
unlockRead(long stamp) |
Release the pessimistic read lock and need to pass in the stamp returned when acquiring the lock. |
validate(long stamp) |
Verify that a write operation occurs during the optimistic read lock, returntrue Indicates that the data has not been modified.false Indicates that the data has been modified |
Extended API
Method name | describe |
---|---|
tryWriteLock() |
Try to acquire the write lock and return immediately if it is not successful. |
tryReadLock() |
Try to acquire the read lock and return immediately if it is not successful. |
tryConvertToWriteLock(long stamp) |
Try to convert the current lock to a write lock, return a new stamp on success, otherwise return 0. |
tryConvertToReadLock(long stamp) |
Try to convert the current lock to a read lock, return a new stamp on success, otherwise return 0. |
isWriteLocked() |
Check whether the current lock has a write lock occupied. |
isReadLocked() |
Check whether the current lock has a read lock occupied. |
4. How it is used
(1) Use of write lock
public void updateValue(double deltaX, double deltaY) { long stamp = (); // Get the write lock try { x += deltaX; y += deltaY; } finally { (stamp); // Release the write lock } }
(2) The use of pessimistic reading lock
public double readValue() { long stamp = (); // Get the read lock try { return (x * x + y * y); } finally { (stamp); // Release the read lock } }
(3) Optimistic use of read locks
public double readValueOptimistically() { long stamp = (); // Get optimistic reading lock double currentX = x, currentY = y; if (!(stamp)) { // Verify that the data is consistent stamp = (); // If inconsistent, downgrade to pessimistic reading lock try { currentX = x; currentY = y; } finally { (stamp); // Release the pessimistic reading lock } } return (currentX * currentX + currentY * currentY); }
(4) Use of lock upgrade
public void conditionalUpdate(double deltaX, double deltaY) { long stamp = (); // Get the pessimistic reading lock try { if (x == 0 && y == 0) { // Check the conditions stamp = (stamp); // Upgrade to write lock if (stamp == 0L) { // If the upgrade fails stamp = (); // explicitly obtain the write lock } x += deltaX; y += deltaY; } } finally { (stamp); // Release the lock } }
5. What are the precautions for it
(1) StampedLock cannot be reentranted StampedLock does not support reentrant. If the same thread tries to acquire the lock again (whether read or write lock), it will cause a deadlock.
(2) Lock release requires the correct stamp to be passed in. Each time the lock is added, a unique stamp will be returned. When the lock is released, the corresponding stamp needs to be passed in, otherwise an IllegalMonitorStateException will be thrown.
(3) Write priority strategy StampedLock preferentially meets write lock requests, avoiding the possible write thread hunger problem of read and write locks.
(4) Thread-safe StampedLock is thread-safe, but does not support condition variables, so it cannot use wait or notify directly.
(5) Applicable scenarios Suitable for scenarios where more reads, less writes. Not suitable for frequent writing scenarios, because the contention of write locks will lead to performance degradation.
Summarize
StampedLock is a "unpopular gem" in the Java concurrency tool library. It provides an efficient non-blocking reading mechanism through optimistic reading locks, while avoiding the problem of writing thread hunger. Being familiar with its API and usage scenarios can help you achieve more efficient concurrent control in performance-sensitive scenarios!
The above is the detailed content of Java using StampedLock to implement efficient reading and writing functions. For more information about Java StampedLock's efficient reading and writing, please pay attention to my other related articles!