ReentrantLockPseudoRandom.java
The ReentrantLockPseudoRandom class is a thread-safe pseudo-random number generator that uses an explicit ReentrantLock to guard access to a shared mutable seed. The nextInt(int n) method locks access to ensure exclusive modification of the seed variable, computes the next seed using a bitwise transformation (calculateNext()), and returns a bounded random value. The use of lock.lock() and lock.unlock() ensures mutual exclusion, preventing race conditions among concurrent threads.
Compared to the previous class, AtomicPseudoRandom, which uses lock-free synchronization via an AtomicInteger and a CAS loop, this version uses blocking synchronization. While both are functionally correct and thread-safe, they differ in performance characteristics:
| Feature | AtomicPseudoRandom | ReentrantLockPseudoRandom |
|---|---|---|
| Synchronization type | Lock-free, non-blocking (CAS) | Blocking with ReentrantLock |
| Concurrency performance | Scales better under high contention | May degrade under high contention |
| Fairness/ordering | No fairness guarantees | Configurable fairness (true/false) |
| Starvation risk | Low (eventually succeeds via retries) | Moderate (depending on scheduling) |
| Complexity | Higher (requires retry logic) | Lower (sequential logic within lock) |
| CPU usage under contention | Higher (spins on retry) | Lower (waits on lock) |
In short, AtomicPseudoRandom is more efficient and scalable under high concurrency but more complex and potentially CPU-intensive under contention, while ReentrantLockPseudoRandom is simpler and may be more predictable under moderate load but suffers performance penalties under heavy contention. These two implementations illustrate the trade-offs between nonblocking and blocking synchronization techniques in concurrent programming.
No comments:
Post a Comment