RFR 8017540: Improve multi-threaded contention behavior of BigInteger.toString() radix conversion cache

Aleksey Shipilev aleksey.shipilev at oracle.com
Tue Jun 25 19:53:27 UTC 2013


On 06/25/2013 11:36 PM, Dmitry Nadezhin wrote:
> What about such code ?
> 
> BigInteger getRadixConversionCache(int radix, int exponent) {
>   BigInteger retVal = null;
>   BigInteger[][] pc = powerCache; // volatile read
>   BigInteger[] cacheLine = pc[radix];
>   int oldSize = cacheLine.length;
>   if (exponent >= oldSize) {
>       cacheLine = Arrays.copyOf(cacheLine, exponent + 1);
>       for (int i = oldSize; i <= exponent; i++) {
>           retVal = cacheLine[i - 1].square();
>           cacheLine[i] = retVal;
>       }
>       synchronized (pc) {
>         if (pc[radix].length < cacheLine.length) {
>           pc[radix] = cacheLine;
>           powerCache = pc; // volatile write, publish
>         }
>       }
>   } else {
>       retVal = cacheLine[exponent];
>   }
>   return retVal;
> }

Still the same race. The reader thread sees the full-length cacheLine
early, but the elements are not yet there.

> Is dummy volatile write necessary inside synchronized block ?
>           powerCache = pc; // volatile write, publish
> 

Yes, since you need to have the matched synchronized(pc) otherwise to
produce the pairwise "acquire".

-Aleksey.




More information about the core-libs-dev mailing list