BigInteger objects are a representative example of immutable objects .
Simply put:
Each immutable object is thread safe , but the link to it is not .
For immutable objects, the state is fixed throughout the entire life cycle. Since there is no way to change it, therefore, each “change” operation is equivalent to replacing with a new object. Therefore, after a series of modifications performed in parallel by N threads on a specific link, the value of the result is difficult to predict (some updates may be lost - unnoticed).
The same story belongs to the class Integer . To overcome this limitation, AtomicInteger introduced the JDK5 class.
Unfortunately, there is no AtomicBigInteger class in the JDK. An alternative solution is to wrap an instance of an object using AtomicReference - which works as a proxy server that synchronizes all atomic operations.
I propose the following compact solution that requires JDK 8:
final AtomicReference<BigInteger> valueHolder = new AtomicReference(BigInteger.ZERO);
Using this approach, any method provided by BigInteger can be counted as a lambda expression, for example:
valueHolder.updateAndGet(x -> x.add(BigInteger.valueOf(10)));
To verify the correctness of the solution, you can use this piece of code that sums all integers below 100 using parallel threads (this is a multi-threaded operation):
IntStream.range(0, 100).parallel() .forEach(i -> valueHolder.updateAndGet(x -> x.add(BigInteger.valueOf(i))));
source share