[concurrency-interest] BigDecimal Safe Publication

James james at inaseq.com
Mon Aug 20 08:04:31 EDT 2012


You'd prefer that over a synchronized block assuming low probability of contention?

On 20 Aug 2012, at 12:59, Vitaly Davidovich <vitalyd at gmail.com<mailto:vitalyd at gmail.com>> wrote:


My suggestion is to use AtomicReference.lazySet for publishing like this, if you can tolerate the extra memory overhead.

Sent from my phone

On Aug 20, 2012 7:56 AM, "Vitaly Davidovich" <vitalyd at gmail.com<mailto:vitalyd at gmail.com>> wrote:

Nevermind, I missed the field.  Yeah, this may not work since it's a data race.

Sent from my phone

On Aug 20, 2012 7:55 AM, "Vitaly Davidovich" <vitalyd at gmail.com<mailto:vitalyd at gmail.com>> wrote:

How are you publishing the BD instance to other threads?

Sent from my phone

On Aug 20, 2012 7:52 AM, "James" <james at inaseq.com<mailto: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;
}

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<mailto: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<mailto: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<mailto: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<mailto:Concurrency-interest at cs.oswego.edu>
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120820/115a2479/attachment-0001.html>


More information about the Concurrency-interest mailing list