2014-12-25 14 views
15

Zgodnie z modelem pamięci Java instrukcje można zmieniać tak długo, jak długo trwa wykonanie well-formed.Czy zmiana kolejności Java wpływa na System.currentTimeMillis()?

Zastanawiam się, czy to możliwe, że następujące kody generują następujące dane wyjściowe?

[Kody] [w tym samym wątku]

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

[Wyjście]

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

Jeżeli nie jest możliwe, to co robi JVM/implementacje zrobić, aby temu zapobiec ?

+0

Jeśli nie uruchomisz tego w systemie z zegarem naprawdę bliskim 1 stycznia 1970, prawdopodobnie nie otrzymasz tych dokładnych wartości. Dlaczego JVM zmieni kolejność tych instrukcji? –

+0

@ ElliottFrisch hi. Te dokładne wartości służą do zilustrowania, że ​​a, b i c nie mogą być monotonicznie zwiększane; nie musi być 10, 20 i 15 :-P –

+0

@ ElliottFrisch Co dotyczy, czy istnieje gwarancja, że ​​te 3 System.currentTimeMillis() nie zostaną zmienione przez JVM? –

Odpowiedz

5

Proszę zobaczyć to pytanie Instruction reordering & happens-before relationship in java.

Wierzę, że jeśli nie jesteś w innym wątku, wynik jakiegokolwiek wykonania będzie zawsze zgodny z kolejnością w kodzie. W tej sytuacji, ponieważ nie można go przetworzyć nie w porządku, powinno być dobrze, nawet jeśli twoje pola są widoczne dla innego wątku.

+0

Joseph, dziękuję za szybką odpowiedź. Jednak uważam, że te 3 instrukcje mogą być wykonywane poza kolejnością, ponieważ wywoływanie metod nie jest AKCJĄ zdefiniowanym przez model pamięci Java, a następnie nie istnieje żaden związek przed tymi zdarzeniami. Jeśli int a = 1 + 1, int b = 2 + 2 w tym samym wątku można zmienić i wykonać jako int b = 2 + 2, int a = 1 + 1, to co jest specjalnym z System.currentTimeMillis(), że sprawia, że ​​muszą być wykonane w kolejności? –

+0

W praktyce 'currentTimeMillis' jest uważane za" to połączenie zewnętrzne, więc nie wiem, co robi i nie będę go zamawiał ponownie ". W przeciwnym razie załóżmy, że re-procesor wie, jak to działa, gdyby ta metoda została zaimplementowana wyłącznie w języku Java, musiałaby odczytać zmienną zmienną (zegar systemowy). Tak czy inaczej, nie powinno być ponownie zamówione. – Sebi

+0

@Sebi, podoba mi się twoje wnioskowanie; każde odniesienie może to udowodnić? –

1

Z powodu bycia wywołanym przez użytkownika, kompilatory nie powinny zmieniać ich kolejności w tym samym wątku. Gdyby to nie było prawdą, moglibyśmy nawet doświadczyć efektów zmiany kolejności w System.out.println (wartości niezależne); Domyślam się, że dostęp do zegara systemowego/systemu operacyjnego tworzy rodzaj relacji między tymi operacjami (zawsze dla bieżącego wątku), więc teoretycznie istnieje pewien rodzaj zależności między nimi. Prawdopodobnie JVM rozważa ten problem i nigdy nie zmienia kolejności wywołań systemu użytkownika.

+0

Kto mówi, że currentTimeMillis jest wywołaniem systemowym? To jest szczegół implementacji. – usr

+0

Jest to szczegół wdrożenia tak, ale w rzeczywistości obecna implementacja nie wykorzystuje zasobów systemowych? Jeśli tak, może to zostać ocenzurowane przez JVM i uniknąć ponownego zamawiania. Jeśli domyślna implementacja nie zawiera wywołań systemowych, to może być inaczej. –

+0

Czy mówisz, że wywołania metod "natywnych" nie mogą być ponownie zamówione? –

Powiązane problemy