✅ Requirements
- Thread-safe: Safe for concurrent calls from multiple threads.
- Non-blocking: No
synchronized
, no locks. - Returns:
BigInteger
values doubling each time →1, 2, 4, 8, 16, ...
🧠 Idea
We can use:
- A single
AtomicReference<BigInteger>
to hold the current value. - Use CAS (compare-and-set) to update it non-blockingly.
🔧 Code: Lock-Free Sequence Generator
import java.math.BigInteger;
import java.util.concurrent.atomic.AtomicReference;
public class PowerOfTwoGenerator {
private final AtomicReference<BigInteger> current = new AtomicReference<>(BigInteger.ONE);
public BigInteger next() {
BigInteger prev, next;
do {
prev = current.get();
next = prev.shiftLeft(1); // multiply by 2
} while (!current.compareAndSet(prev, next));
return prev;
}
}
💡 How It Works
shiftLeft(1)
is equivalent to multiplying by 2.compareAndSet(prev, next)
ensures atomic, lock-free update:- If
current
is still equal toprev
, it sets it tonext
. - If another thread updated it, retry.
- If
🧪 Example Usage
public class Main {
public static void main(String[] args) {
PowerOfTwoGenerator gen = new PowerOfTwoGenerator();
for (int i = 0; i < 10; i++) {
System.out.println(gen.next());
}
}
}
Output:
1
2
4
8
16
32
64
128
256
512
✅ Thread-Safe? Yes.
- Multiple threads can call
next()
concurrently without data races. - No
synchronized
, no locks — just atomic CAS.