AtomicPseudoRandom.java
import java.util.concurrent.atomic.*;
/**
* AtomicPseudoRandom
* <p/>
* Random number generator using AtomicInteger
*
*/
//ThreadSafe
public class AtomicPseudoRandom {
private AtomicInteger seed;
AtomicPseudoRandom(int seed) {
this.seed = new AtomicInteger(seed);
}
public int nextInt(int n) {
while (true) {
int s = seed.get();
int nextSeed = calculateNext(s);
if (seed.compareAndSet(s, nextSeed)) {
int remainder = s % n;
return remainder > 0 ? remainder : remainder + n;
} else {
System.out.println(".");
}
}
}
private int calculateNext(int n) {
n ^= (n << 6);
n ^= (n >>> 21);
n ^= (n << 7);
return n;
}
public static void main(String... args) {
AtomicPseudoRandom apr = new AtomicPseudoRandom(50); //change this value, rerun, until you see some . print
int totalThreads = 100000;
for(int i = 0; i < totalThreads; i++) {
// new Thread(() -> System.out.print(apr.nextInt(5))).start();
new Thread(() -> apr.nextInt(5)).start();
}
System.out.println(apr.nextInt(5));
}
}
The AtomicPseudoRandom
class is a thread-safe pseudo-random number generator built using an AtomicInteger
to hold the internal seed. It uses a CAS (Compare-And-Set) loop to atomically update the seed on each call to nextInt(int n)
, ensuring that concurrent threads can safely generate random numbers without explicit locking. The method computes the next seed using bitwise operations (calculateNext
) and attempts to set it using compareAndSet()
. If the CAS fails due to a concurrent modification, the loop retries until it succeeds, printing a dot (.
) to indicate contention. This design showcases a practical application of atomic variables to implement a lock-free, scalable utility class suitable for high-concurrency environments. The main
method spawns 100,000 threads to generate values in parallel, highlighting both the nonblocking behavior and performance of CAS-based synchronization.
No comments:
Post a Comment