Site Search:

AtomicPseudoRandom.java

 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