简体   繁体   中英

On a 64 bit JVM is reading and writing of a double atomic?

I'm doing some research on proper synchronization of Java code and came accross multiple instances were it was declared that reading/writing of doubles and longs is not atomic.

So I wrote a simple benchmark and found doubles were generally faster (by a hair) and the only time I noticed a big difference was when I had an error in the code and I was converting back and forth between double and float (preserved as 3rd test case). Once the math was pure double or pure float, benchmarks was almost exactly the same. (Java 1.8, 64bit Oracle JVM)

However, I've read that doubles and long read and writes were not atomic, but treated as 2 32 bit reads and writes by the JVM.

Shouldn't I expect a performance difference?

 public class Benchmark { static double loopDouble (double aAddValue) { double tResult = 0.0; while (tResult < 10000000.0) { tResult += aAddValue; } return tResult; } static double loopFloat (float aAddValue) { double tResult = 0.0; while (tResult < 10000000.0) { tResult += aAddValue; } return tResult; } static float loopFloatFloat (float aAddValue) { float tResult = 0.0f; while (tResult < 10000000.0f) { tResult += aAddValue; } return tResult; } static double loopInt (int aAddValue) { double tResult = 0.0; while (tResult < 10000000.0) { tResult += aAddValue; } return tResult; } public static void main(String[] args) { long doubleTimeNs = - System.nanoTime(); loopDouble(1.0); doubleTimeNs += System.nanoTime(); long floatTimeNs = - System.nanoTime(); loopFloat(1.0f); floatTimeNs += System.nanoTime(); long floatfloatTimeNs = - System.nanoTime(); loopFloatFloat(1.0f); floatfloatTimeNs += System.nanoTime(); long intTimeNs = -System.nanoTime(); loopInt(1); intTimeNs += System.nanoTime(); long doubleTime2Ns = - System.nanoTime(); loopDouble(1.0); doubleTime2Ns += System.nanoTime(); System.out.println("Double: " + doubleTimeNs + " (" + doubleTime2Ns + ") "+ " Float: " + floatTimeNs + " Float-float: " + floatfloatTimeNs + " Int: " + intTimeNs); } } Double: 23944257 (23736683) Float: 24220307 Float-float: 24134056 Int: 25745599

Pointed out by Kelly Denehy. JLS section 17.7

"For the purposes of the Java programming language memory model, a single write to a non-volatile long or double value is treated as two separate writes: one to each 32-bit half. This can result in a situation where a thread sees the first 32 bits of a 64-bit value from one write, and the second 32 bits from another write.

Writes and reads of volatile long and double values are always atomic.

Writes to and reads of references are always atomic, regardless of whether they are implemented as 32-bit or 64-bit values. "

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM