[concurrency-interest] Question about final field semantic in case of a race

Thomas Krieger thomas.krieger at vmlens.com
Thu Aug 31 05:17:11 EDT 2017


Hi,

I am running the following JCStressTest on a Raspberry Pi 3 with a Java(TM) SE Runtime Environment (build 1.8.0_65-b17) Java HotSpot(TM) Client VM (build 25.65-b01, mixed mode):

@JCStressTest
@Outcome(id = "0", expect = Expect.ACCEPTABLE, desc = "Default outcome.")
@State
public class BigDecimalToString {
    private final  BigDecimal testBigDecimal = new BigDecimal("0.56");
    @Actor
    public void actor1(IntResult1 r) {
        testBigDecimal.toString().length();
    }
    @Actor
    public void actor2(IntResult1 r) {
        testBigDecimal.toString().length();
    }    
}

In about half of the iterations, I see the following Exception:
java.lang.NullPointerException
at java.lang.String.length(String.java:623)
at com.vmlens.stressTest.tests.BigDecimalToString.actor1(BigDecimalToString.java:12)
at com.vmlens.stressTest.tests.BigDecimalToString_jcstress.actor1(BigDecimalToString_jcstress.java:145)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

The NullPointerException happens at this statement: return value.length. The BigDecimal toString method caches the String leading to race:
@Override
    public String toString() {
        String sc = stringCache;
        if (sc == null)
            stringCache = sc = layoutChars(true);
        return sc;
    }
    /**
     * Used to store the canonical string representation, if computed.
     */
    private transient String stringCache;

But the field "value" of the Class String is final. So my question:
Is the behavior of the test the expected result?  The JLS spec (17.5) states: "A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.". In my test, a thread can get a reference to a String which has not been completely initialized and the NullPointerException is a
consequence of the Race. Or, because of the final field, all threads should have only seen an initialized value?


Thank you very much
Thomas Krieger
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20170831/1e3e7d65/attachment.html>


More information about the Concurrency-interest mailing list