19

According to Java Memory Model, instructions can be reordered as long as the execution is well-formed.

So I wonder, is it possible that the following codes produces the following output?

[codes][in a same thread]

long a = System.currentTimeMillis();
long b = System.currentTimeMillis();
long c = System.currentTimeMillis();

[output]

a == 10, b == 20, c == 15

If not possible, then what does JVM / implementations do to prevent this from happening?

Joshua
  • 40,822
  • 8
  • 72
  • 132
Kurtt.Lin
  • 289
  • 1
  • 8
  • Unless you run this on a system with the clock set really close to January 1 1970 you probably won't get those exact values. Why would the JVM reorder those instructions? – Elliott Frisch Dec 25 '14 at 03:45
  • @ElliottFrisch hi. Those exact values are used to illustrate that a, b, and c may not be monotonically increasing; does not have to be 10, 20 and 15 :-P – Kurtt.Lin Dec 25 '14 at 05:30
  • @ElliottFrisch What I concern here is, is there a guarantee that these 3 System.currentTimeMillis() would not be reordered by the JVM? – Kurtt.Lin Dec 25 '14 at 05:33
  • 3
    System.currentTimeMillis() is a user space system call and executing system calls out of order should be a bug in any system. – Peter Lawrey Dec 25 '14 at 08:00
  • What would be the benefit of executing these methods out of order given they are the same. The JIT and CPU don't execute things out of order randomly, but when there is an apparent performance gain. – Peter Lawrey Dec 25 '14 at 08:01
  • 1
    I believe that [this post on the `concurrency-interest` mailing list](http://cs.oswego.edu/pipermail/concurrency-interest/2012-August/009880.html) should be of interest here, as well as that entire thread. – Marko Topolnik Dec 25 '14 at 08:32
  • @PeterLawrey they are not the same - they observe a side effect meaning that being out of order is a visible effect on the behavior of the problem. This definitely looks like a bug to me. – Benjamin Gruenbaum Dec 25 '14 at 09:32
  • If I had to guess by the way - it's due to the fact `currentTimeMillis` is simply not accurate enough. – Benjamin Gruenbaum Dec 25 '14 at 09:33
  • 1
    @BenjaminGruenbaum accuracy doesn't matter as there is always a point that one milli-second becomes another. – Peter Lawrey Dec 25 '14 at 10:17
  • Intuitively, if JVM does not know what some particular method calls do, it can not reorder them, so that "unknown" code gets executed in different order. I mean, reordering without knowing if it is ok sounds... fundamentally broken. And, in this case, if JVM *does* know what *these* methods do, it also knows it must not reorder them. – hyde Dec 25 '14 at 10:41
  • @hyde the JVM might *know* what `currentTimeMillis` does. It could simply be a static field load. – usr Dec 25 '14 at 12:35
  • @usr Return value of `currentTimeMillis` could not simply be a static field... It's a changing value after all. It might be `volatile`, but then it would be `volatile` and there would be no problem. – hyde Dec 25 '14 at 13:38
  • @hyde it could be a non-volatile static field being written to by a timer periodically. The JVM is not bound by any rules as long as no deviation from the standard is detectable. – usr Dec 25 '14 at 15:19
  • @usr Omitting some kind of memory boundary from a function like this would be a bug, so that is kind of irrelevant (it *could* also be buggy in many other ways). Mechanisms like `volatile` exist for a reason. – hyde Dec 25 '14 at 20:16

2 Answers2

5

Please see this question Instruction reordering & happens-before relationship in java.

I believe that unless you are in a different thread, the outcome of any execution will always be consistent with the order in your code. In this situation, since it is impossible to process it out of order, it should be good even if your fields are visible to another thread.

Community
  • 1
  • 1
Joseph K. Strauss
  • 4,683
  • 1
  • 23
  • 40
  • Joseph, thank you for your quick answer. However, I tend to believe these 3 instructions may be executed out of order, because invoking methods is not an ACTION defined by the Java Memory Model, then no happens-before relationship exists for these 3 instructions. If int a=1+1, int b=2+2 in a same thread can be reordered and executed as int b=2+2, int a=1+1, then what is the special of System.currentTimeMillis() that makes them must be executed in order? – Kurtt.Lin Dec 25 '14 at 05:26
  • In practice, `currentTimeMillis` is an either regarded as "it is external call, so I don't know what it does and I will not re-order it". Otherwise let's assume the re-orderer knows how it works, if this method would be implemented purely in java it would have to read some volatile variable (system clock). Either way, it shouldn't be re-ordered. – Sebi Dec 25 '14 at 12:32
  • @Sebi, I like your inference; any reference can prove it? – Kurtt.Lin Dec 26 '14 at 03:37
  • @Kurtt.Lin I've just checked, and this method is defined as: `public static native long currentTimeMillis();` (in JDK6 b33). So my guess is that it's not re-ordered since it's `native`. (That's only my guess, but I can't think of a way to determine whether or not a native method can be re-ordred) – Sebi Dec 27 '14 at 15:58
  • 1
    Whether the action associated with a `currentTimeMillis()` call can get reordered, is irrelevant, as the result of `currentTimeMillis()` is not guaranteed to be monotonically increasing anyway. E.g., there could be a leap-second correction or an NTP update right between two calls. – Holger Sep 22 '20 at 07:55
0

Due to being a user system call, compilers shouldn't reorder them in the same thread. If this was not true, we could even experience reordering effects in System.out.println(independent values); I guess that access to the System's/OS's clock creates a sort of relationship between these operations (always for the current thread), so theoretically there is some kind of dependency between them. Probably, JVM considers this issue and never reorders User System calls.

Kostas Kryptos
  • 4,081
  • 2
  • 23
  • 24
  • 1
    Who says that currentTimeMillis is a system call? That's an implementation detail. – usr Dec 25 '14 at 12:33
  • It is an implementation detail yes, but actually current implementation doesn't it uses system resources? If yes then this may be censored by JVM and avoids reordering. If default implementation didn't include a system call things maybe different. – Kostas Kryptos Dec 25 '14 at 14:20
  • Are you saying `native` method calls cannot be re-ordered? – Sotirios Delimanolis Dec 25 '14 at 14:40
  • No, I say that it would be buggy to reorder calls that include at least an external call in their implementation. Hopefully, JVM may decide to reorder calls for which it has 100% control. How could it know if performance may be gained if there is a dependency on a system resource for which it has no control? – Kostas Kryptos Dec 25 '14 at 15:41