I have a requirement to update a global BigInteger
value via multiple threads -- is BigInteger
thread safe?
The BigInteger class stores a number as an array of unsigned, 32-bit integer "digits" with a radix, or base, of 4294967296.
The standard library BigInteger class in Java is known to be notoriously slow (at least for Java 7 and earlier, and I doubt Java 8 is any different).
BigInteger has no cap on its max size (as large as the RAM on the computer can hold).
3. BigInteger Larger Than Long. MAX_VALUE. As we already know, the long data type is a 64-bit two's complement integer.
BigInteger objects are an representative example of immutable objects.
To put it simply:
Each immutable object is thread-safe, but the reference to it is not.
For immutable objects the state is fixed for an entire lifetime. Because there is no option to change it therefore each "change" operation is equivalent to replacement by a new object. So after series of modifications performed parallely by N threads on a specific reference the result value is hard to predict (some updates could be lost - unnoticed).
The same story is with Integer class. To overcome that limitation AtomicInteger class was introduced to JDK5.
Unfortunately there is no "AtomicBigInteger" class in JDK. The alternate solution is to wrap an object instance with AtomicReference - which works as a proxy that makes all operations synchronised and atomic.
I propose a following compact solution that requires JDK 8:
final AtomicReference<BigInteger> valueHolder = new AtomicReference(BigInteger.ZERO);
Using this approach any method provided by BigInteger could be restated as a lambda expression, e.g.:
valueHolder.updateAndGet(x -> x.add(BigInteger.valueOf(10)));
To check if the solution is correct you may use this code snippet that sums up all integers lower than 100 using parallel streams (it is multithread operation):
IntStream.range(0, 100).parallel()
.forEach(i -> valueHolder.updateAndGet(x -> x.add(BigInteger.valueOf(i))));
You cannot update BigInteger, read javadoc, it's Immutable arbitrary-precision integers.. To update a BigInteger field you will need to replace it with a new BigInteger, like this
...
bigInteger = bigInteger.add(value);
...
and this will require synchronization otherwise two things may happen:
one thread changed the value but other threads do not see the change
two or more threads are adding simultaneously but some addings are lost.
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