[concurrency-interest] BigDecimal Safe Publication

Zhong Yu zhong.j.yu at gmail.com
Mon Aug 20 13:58:04 EDT 2012


On Mon, Aug 20, 2012 at 6:49 AM, James <james at inaseq.com> wrote:
> I have a system that processes a lot of Doubles.  From time to time I need
> the accuracy of BigDecimal math but creating a BigDecimal is relatively
> expensive so I only do it when needed.  Hence I use lazy initialization as
> shown below.
>
> private Double price;  // although not final is effectively immutable and
> guaranteed non-null when used below
> private transient BigDecimal priceBD;
>
> public BigDecimal getPriceBD() {
> if (priceBD == null) {
> priceBD = BigDecimal.valueOf(price);  // strict singleton semantics not
> required
> }
> return priceBD;
> }

You may have omitted it for brevity, but a local variable is necessary
here for correctness. See String.hashCode()

> This particular construction method does not use one of the MathContext
> based constructors but it was while investigating the thread safety of this
> approach that I noticed that some of the constructors may not be safe.
>
> My concern is whether using this technique a second thread might see a
> BigDecimal that is not fully initialized.  I'm pretty sure it can, but it
> wouldn't matter if the volatile intVal is enforcing happens-before in
> subsequent calls to the BigDecimal, however the constructors that delegate
> to the method mentioned do things after setting the intVal.
>
> On 20 Aug 2012, at 12:32, Sergey Kuksenko <skuksenko at gmail.com> wrote:
>
> Hi James,
>
> - Look into jdk8 sources. New  BigDecimal has final fields (instead of
> volatile).
> - Could you explain what is the issue for safe publication in the old code
> (look like everything is ok)?
>
> On Mon, Aug 20, 2012 at 2:58 PM, James <james at inaseq.com> wrote:
>>
>> I'm wondering whether the BigDecimal constructors that take a MathContext
>> parameter exhibit initialization safety.  As far as I can tell (and I could
>> be very wrong), BigDecimal is relying on the volatile nature of the intVal
>> reference to ensure the BigDecimal is effectively immutable.  However, the
>> constructors that take a MathContext delegate to the following method, which
>> alters other members after intVal:
>>
>>     private void roundThis(MathContext mc) {
>>         BigDecimal rounded = doRound(this, mc);
>>         if (rounded == this)                 // wasn't rounded
>>             return;
>>         this.intVal     = rounded.intVal;
>>         this.intCompact = rounded.intCompact;
>>         this.scale      = rounded.scale;
>>         this.precision  = rounded.precision;
>>     }
>>
>> Is this a potential issue for safe publication or am I missing something?
>> Is BigDecimal intended to exhibit initialization safety?
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
>
> --
> Best regards,
> Sergey Kuksenko
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>


More information about the Concurrency-interest mailing list