A lot of our code is legacy but we are moving to a "Big Data" back-end and I'm trying to evangelize the newer API calls, encourage the use of the latest Spring libraries etc. One of our problems is application layer ID generation. For reasons I don't understand, a higher authority wants sequential BigInteger's. I would have made them random with re-generate and re-try on failed insertions but I done got vetoed.
Grumbling aside, I'm in a position where I need to increment and get a BigInteger across threads and do it in a safe and performant manner. I've never used AtomicReference before but it looks pretty close to perfect for this application. Right now we have a synchronized code block which hurts our performance pretty badly.
Is this the right way to go? Syntax examples?
I should mention that the way this module works, it hits the database using a Stored Procedure to grab a range of values to use. Tens of thousands at a time so that it only happens maybe once in 20 minutes. This keeps the various servers from stepping on each-other but it also adds the wrinkle of having to set the BigInteger to an arbitrarily subsequent value. Of course, that needs to be thread safe also.
P.S. I still think my random generation idea is better than handling all this threading stuff. A BigInteger is a ridiculously large number and the odds of ever generating the same one twice have to be close to nil.
You can have it like this. for(BigInteger a = BigInteger. ONE; a. compareTo(someBigInteger); a=a.
BigInteger is immutable and as such it is safe for access by multiple threads. Side-note: Thread-safety is a term that deals with multiple threads accessing a piece of code (not just a variable).
As we know, the BigInteger class is used for mathematical operations which involve very big integer calculations larger than the primitive long type. It represents immutable arbitrary-precision integers.
The equivalent of Java long in the context of MySQL variables is BigInt. In Java, the long datatype takes 8 bytes while BigInt also takes the same number of bytes.
It is possible using AtomicReference here's a quick draft :
public final class AtomicBigInteger {
private final AtomicReference<BigInteger> valueHolder = new AtomicReference<>();
public AtomicBigInteger(BigInteger bigInteger) {
valueHolder.set(bigInteger);
}
public BigInteger incrementAndGet() {
for (; ; ) {
BigInteger current = valueHolder.get();
BigInteger next = current.add(BigInteger.ONE);
if (valueHolder.compareAndSet(current, next)) {
return next;
}
}
}
}
It is basically a copy of the AtomicLong code for incrementAndGet()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With