4 ms·
The issue may be to do with the guarantees that the JVM gives you about orders of operations and write visibility across threads. The author hints at a possibl
by joncrocks 9y ago
The issue may be to do with the guarantees that the JVM gives you about orders of operations and write visibility across threads.
The author hints at a possible solution when they say "As we see a non-volatile field stringCache", the key being 'volatile' which is a Java keyword with a specific meaning that constrains the order of operations and write visibility across threads.
See http://tutorials.jenkov.com/java-concurrency/java-memory-model.html http://tutorials.jenkov.com/java-concurrency/java-memory-mod... for a reasonable explanation.
edit: suggestion elsewhere that it could be a wonky JVM implementation, so may not be a BigDecimal problem after all
- exDM69 9y ago> the key being 'volatile' which is a Java keyword with a specific meaning that constrains the order of operations and write visibility across threads. I must point out that "volatile" in Java means something completely different than what it means in C and related languages. In multithreaded C code, "volatile" is almost always incorrect. There are only a few correct and portable uses of volatile (such as dealing with setjmp or unix signal handlers).
- dfox 9y agoEven for setjmp() it is better to organize your code such that you don't need to declare anything to be volatile.
- _pmf_ 9y agoThe most important thing being that in Java, volatile is a memory barrier, whereas in C it isn't. One thing I'm unsure of: I think in C, a volatile write to some location and a volatile write to another location (even without any data dependency) may not be reordered); is this correct?
- mikeash 9y agoC's volatile guarantees very little. It's mostly there for compilers to implement in whatever way is useful for the environment they run in, and so there isn't much portable code you can usefully write using volatile. All it really guarantees is that reads and writes won't be elided. For example: *x = 42; *x = 43; If x is a normal pointer, the compiler can eliminate the first line. If it's a pointer to volatile, the compiler must write both values. Volatile predates multithreading in C (it was meant for memory-mapped IO and similar things) and hasn't been updated for it, so it has pretty much no useful properties for multithreading. There are no guarantees about reordering when it comes to multiple threads. You're guaranteed to see reads and writes in the correct order from the perspective of the thread your code is running on, but the compiler won't insert any memory barriers, so it's completely up for grabs how other threads might see it. (More completely, it depends entirely on your CPU's memory model. If you're on an architecture which does strict ordering at the hardware level then you could potentially take advantage of that. If you aren't then you'll see whatever crazy results hardware reordering might produce.) In contrast, Java's volatile is only about multi-threading. So really, the only thing that's similar between the two languages' use of volatile is how they spell the keyword.
- juancn 9y agoIt's a bug in the JVM, value is final and assigned in the constructor after the array is fully initialized, so it's impossible as per the JMM to see a partially initialized string. My guess is that the RaspPi VM is buggy.
- xxs 9y agostringCache is a red herring. While it publishes the string result unsafely, any string should be safe for use at any thread.