Inhaltsverzeichnis
Frageninhalt
nanotime hat einen willkürlichen 0-Punkt (das Erhalten einer Nanotime von 0 hat keine besondere Bedeutung), daher besteht keine Notwendigkeit, es überhaupt aufzurufen, außer das, was es zurückgibt, mit den Ergebnissen verschiedener Nanotime-Aufrufe zu vergleichen. Nanotime verfolgt die verstrichene Zeit, das ist alles.
...但我需要单调递增的时间戳!
currenttimemillis
nanotime
问题
Heim Java Warum unterscheidet sich die über ein großes Zeitfenster berechnete verstrichene Zeit zwischen System.currentTimeMillis und System.nanoTime um bis zu 100+ Millisekunden?

Warum unterscheidet sich die über ein großes Zeitfenster berechnete verstrichene Zeit zwischen System.currentTimeMillis und System.nanoTime um bis zu 100+ Millisekunden?

Feb 09, 2024 am 10:24 AM
overflow

Der Herausgeber von PHP Apple erklärt, warum die in einem großen Zeitfenster berechnete verstrichene Zeit einen Unterschied von bis zu 100+ Millisekunden zwischen System.currentTimeMillis und System.nanoTime aufweist. Dieses Problem betrifft den zugrunde liegenden Mechanismus des Computersystems und die Planungsmethode des Betriebssystems. Bei der Berechnung der verstrichenen Zeit verwendet System.currentTimeMillis die vom Betriebssystem bereitgestellte Uhrzeit, während System.nanoTime CPU-Taktzyklen verwendet. Aufgrund des Planungsmechanismus des Betriebssystems und der asynchronen Natur der Hardware-Uhr führen diese beiden Timing-Methoden zu Zeitunterschieden. Die spezifischen Gründe und Lösungen werden in den folgenden Artikeln ausführlich vorgestellt.

Frageninhalt

Ich versuche, eine ksuid zu erstellen, die eine Mikrosekunden-Präzessionssortierung in derselben JVM durchführen kann. Da currenttimemillis nur Millisekundengenauigkeit liefert, sollten Sie in Betracht ziehen, currenttimemillis () und nanotime () zusammen zu verwenden, um den ersten Moment zu erfassen. Der Nanozeitunterschied beträgt berechnet als Anzahl der Mikrosekunden, die seit dem ersten Zeitpunkt vergangen sind, und als Wert ab dem zweiten Zeitpunkt. Verwenden Sie die aus der Nanozeit berechnete verstrichene Zeit und addieren Sie sie zu den anfänglichen Millisekunden, sodass wir die Epoche zu jedem Zeitpunkt nach dem Start des JVM (alle innerhalb desselben JVM) mit Mikrosekundengenauigkeit berechnen können.

//Statische Sammlung der anfänglichen Nanozeit und Strommillis 最终长 inittimenanos = system.nanotime();最终长 inittimemillis = system.currenttimemillis();

// Wenn von nun an die aktuelle Zeit mit Mikro-/Nanosekundengenauigkeit erforderlich ist, berechnen Sie die verstrichene Zeit aus der Nanozeit und addieren Sie die verstrichenen Millisekunden zu initialmillis. Die verbleibende verstrichene Zeit ergibt dann die Zeit mit Mikrosekundengenauigkeit

final long elapsednanotime = system.nanotime() - inittimenanos;最终双精度 elapsedmillisfromnanotime = elapsednanos / (1000000.0);

//Monoton steigende Zeitstempel-Millisekunden seit dem Start von JVM (Epoche, wir nennen es vielleicht nicht Epoche) final 长计算当前时间millis = inittimemillis + elapsedmillisfromnanotime; final long nanosprecision = elapsednanos % 1000000; //Zusätzliche Zeitpräzision durch Nanozeit

Erwägen Sie, diese Werte zu verwenden, um eine monoton ansteigende ksuid zu generieren, die sich der aktuellen Zeit annähert, aber garantiert nach der Erstellungszeit innerhalb derselben JVM sortiert wird. Da currenttimemillis keine monoton ansteigende Zeitstempelgarantie bietet, sollten Sie diesen Ansatz zum Generieren in Betracht ziehen ungefähr Monoton ansteigender Zeitstempel des realen Zeitstempels (kann um einige Millisekunden variieren, sofern keine Anpassungen der Schaltsekunden an der Epochenzeit vorgenommen werden). Es wurde erwartet, dass sich die mit Epoche und Nanozeit berechnete verstrichene Zeit um einige Millisekunden unterscheidet, aber der tatsächliche Unterschied schwankte sehr häufig, und als ich den folgenden Test 48 Stunden lang durchführte, beobachtete ich einen Unterschied von bis zu 150 Millisekunden zwischen den beiden. In den meisten Fällen ist die mit Nanotime berechnete verstrichene Zeit höher als die mit currenttimemillis berechnete verstrichene Zeit, und die beobachteten Zeiten liegen zwischen -2 Millisekunden und +150 Millisekunden.

final long elapsedmillis = system.currenttimemillis() - inittimemillis; //Verstrichene Zeit in Millisekunden von system.currenttimemillis() 最终双方差millis = elapsedmillisfromnanotime - elapsedmillis; //Varianz der verstrichenen Zeit

Übersehe ich etwas über JVM-Timing-Garantien? Ist die Methode zur Berechnung monoton ansteigender ungefährer Zeitstempel falsch? (Dies wird nicht als tatsächliche Epoche im System verwendet, sondern nur zum Generieren der UUID, die auch den ungefähren Zeitstempelzeitpunkt innerhalb derselben JVM darstellt.)

//Testklasse

package org.example;

import java.util.concurrent.TimeUnit;

public class Main {
    public static void main(String[] args) throws Exception {
        final long initTimeNanos = System.nanoTime();
        final long initTimeMillis = System.currentTimeMillis();
        System.out.println("Nanos: " + initTimeNanos);
        System.out.println("Millis: " + initTimeMillis);

        while (true) {
            final long currentNanos = System.nanoTime();
            final long elapsedNanos = currentNanos - initTimeNanos;
            final double elapsedMillisFromNanos = elapsedNanos / 1000000.0;
            final long elapsedMillis = System.currentTimeMillis() - initTimeMillis;
            final double varianceMillis = elapsedMillisFromNanos - elapsedMillis;
            if (Math.abs(varianceMillis) > 1) {
                System.out.printf("\nVariance Observed: %.6f\n", varianceMillis);
                System.out.printf("Elapsed Time: %.6fms (from System.nanoTime)\n", elapsedMillisFromNanos);
                System.out.printf("Elapsed Time: %dms (from System.currentTimeMillis)\n", elapsedMillis);
            }
            if (elapsedMillis > TimeUnit.HOURS.toMillis(48)) {
                break;
            }
            Thread.sleep(5000);
            System.out.print(".");
        }
    }
}
Nach dem Login kopieren

Warum ändert sich die Varianz der verstrichenen Zeit ständig? Was ist die maximale Varianz, die wir erwarten können, wenn der JVM ein Jahr lang ununterbrochen läuft (jeder JVM garantiert hierfür eine Ober- oder Untergrenze, getestet mit Mac und Windows, Mac ergab einen langsamen Anstieg der Varianz, Windows war viel schneller)?

Ich gehe davon aus, dass die verstrichene Zeit um weniger als 10 Millisekunden schwankt und die Änderungen seltener auftreten. Die tatsächliche Beobachtung ist jedoch, dass sich die Varianz ständig ändert und nach oben und unten schwankt, wobei innerhalb von 48 Stunden bis zu 150 Millisekunden beobachtet werden. Im Allgemeinen messen Nanotime und CTM völlig unterschiedliche Dinge und können nicht gemischt werden.

nanotime hat einen willkürlichen 0-Punkt (das Erhalten einer Nanotime von 0 hat keine besondere Bedeutung), daher besteht keine Notwendigkeit, es überhaupt aufzurufen, außer das, was es zurückgibt, mit den Ergebnissen verschiedener Nanotime-Aufrufe zu vergleichen. Nanotime verfolgt die verstrichene Zeit, das ist alles.

system.ctm ruft die Systemuhr ab. Wenn Sie Posix verwenden

was wird zurückgegeben? CTM ist im Allgemeinen auch viel langsamer als Nanotime. ctm hat auch eine klar definierte 0, die Mitternacht UTC am 1. Januar 1970 darstellt.

Frage: „Ich möchte, dass die aktuelle Zeit mit Nanosekundengenauigkeit mit der Systemuhr übereinstimmt“ ist auf JVM

nicht möglichdate 命令或在系统设置中编辑系统的时间设置,则不会影响 nanotime,但会更改 system.ctm.

时间涂抹是指某些网络时间守护程序注意到您的系统时钟略有偏差,并且不只是将系统时钟编辑到正确的时间,而是引入了涂抹:假设您比实时时间“提前”了 400 毫秒。 ntp 可以将您的时钟向后设置 400 毫秒,但许多日志记录系统假设 system.ctm 不会向后移动(这是一个不正确但广泛应用的假设)。

这可以通过让时间放慢一段时间来“修复”:每经过 100 毫秒,ntp 守护进程就会将时钟“保持”在同一毫秒上一毫秒。每 100 毫秒就赶上 1 毫秒,因此在 400,000 毫秒(仅 400 秒)内,时钟恢复与网络同步,并且日志记录根本不受影响。

但是,这显然会完全破坏 system.ctm 和 nanotime 之间的任何关系!

大多数 ntp 都是这样涂抹的(它们也会向前涂抹 - 如果您的系统时钟落后,它不仅仅会向前跳跃:这会使日志撒谎(使其看起来就像两个事件之间存在一些间隙)比实际大得多),因此每 100 毫秒,ntp 就会使时钟跳过一毫秒,类似这样的事情,以赶上。

...但我需要单调递增的时间戳!

那么 nanotime 就无关紧要了。不要使用它。

拥有一些提供 id 的集中“商店”。一种实现:

class TimeStore {
  long lastVal = 0L;

  public synchronized long get() {
    long mark = System.currentTimeMillis() << 4;
    return lastVal = Math.max(mark, lastVal + 1);
  }
}
Nach dem Login kopieren

这将返回当前时间,左移 4 位,并将填充此移位“释放”的 16 个值,以便能够在同一时间生成单调递增值,最多 16 次;同一毫秒内的任何进一步请求都会潜入下一毫秒。

尽管如此,这可能并不比nanotime慢。

rzwitserloot的回答是正确的。我将向您提供我对各种问题的看法。

currenttimemillisnanotime 无关

system.currenttimemillissystem.nanotime 彼此无关。

  • currenttimemillis 从主机的硬件时钟单元检索当前日期和时间,由主机操作系统管理。
  • nanotime 来自主机 cpu 保存的计数。

currenttimemillis

所以首先要了解人类的年月日和时分秒的概念。传统计算机中使用的时钟硬件的分辨率有限,有些是毫秒,有些是微秒,但没有纳秒。

由于各种原因,本次通话报告的日期和时间可能会有所不同。其中一个原因是,在电池电量耗尽的情况下启动的计算机会将其时钟重置为默认时刻,直到通过调用时间服务器进行纠正。另一个原因是系统管理员或用户可能会更改日期时间。还有一个原因是硬件时钟可能无法很好地保持时间,并且会通过调用时间服务器在更新之间运行得快或慢。

nanotime

nanotime 调用以纳秒计数形式告知经过的时间。但这个流逝的时间与日历和墙上的时钟无关。此调用仅返回经过的纳秒的单调计数。

这个计数非常准确,因为它来自计算机的“跳动的心脏”。返回的数量始终在增加,直到达到 long.max_value,然后环绕到 long.min_value。这给出了大约 292 年的范围,但这并不意味着从现在起 292 年。计数的起点未指定。在某些 java 实现中,您可能会看到计数在计算机启动时开始。但并不能保证这一点。

问题

您可能会考虑寻找 新 6、7、8 版本 的实现a href="https://en.wikipedia.org/wiki/universally_unique_identifier" rel="nofollow noreferrer">uuid 被提议给 ietf 进行标准化。

currenttimemillis 在现代 java 中已被 java.time.instant 类取代。调用 instant.now 捕获 utc 中的当前时刻。

java 9+ 中的常见实现以微秒为单位报告,但在 java 8 中以毫秒为单位。 instant 类能够以纳秒为单位。

Smarte Idee. Aber es ist nicht realistisch. Wie oben erwähnt, currenttimemillisnanotime 不相关。最重要的是,currenttimemillis 的结果可能会因多种原因而有所不同。同时,nanotime 计数可能会随着主机的每次启动而变化,并且肯定不会对应于其他计算机上进行的任何 nanotime Anrufe.

Ja, Sie ignorieren die Tatsache, dass die Java-Spezifikation keine der Garantien bietet, die Sie scheinbar annehmen.

Die einzige Garantie in

javadoc ist, dass nanotime 是“高分辨率”,至少与 currenttimemillis genauso gut ist. Und es gibt keine Garantie, wann Sie mit dem Ende von 292 rechnen können.

Gleichzeitig ist currenttimemillis ein bewegliches Ziel und kann sich jederzeit ändern, vorwärts oder rückwärts.

Es ist unvorhersehbar.

Die Java-Spezifikation gibt keine solche Garantie.

Das obige ist der detaillierte Inhalt vonWarum unterscheidet sich die über ein großes Zeitfenster berechnete verstrichene Zeit zwischen System.currentTimeMillis und System.nanoTime um bis zu 100+ Millisekunden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Der Preis von Bitcoin seit seiner Geburt 2009–2025. Die umfassendste Zusammenfassung der historischen BTC-Preise Der Preis von Bitcoin seit seiner Geburt 2009–2025. Die umfassendste Zusammenfassung der historischen BTC-Preise Jan 15, 2025 pm 08:11 PM

Seit seiner Einführung im Jahr 2009 hat sich Bitcoin zu einem führenden Unternehmen in der Welt der Kryptowährungen entwickelt und sein Preis hat enorme Schwankungen erfahren. Um einen umfassenden historischen Überblick zu bieten, stellt dieser Artikel Bitcoin-Preisdaten von 2009 bis 2025 zusammen und deckt wichtige Marktereignisse, Änderungen der Marktstimmung und wichtige Faktoren ab, die die Preisbewegungen beeinflussen.

Überblick über den historischen Preis von Bitcoin seit seiner Geburt. Vollständige Sammlung historischer Preistrends von Bitcoin. Überblick über den historischen Preis von Bitcoin seit seiner Geburt. Vollständige Sammlung historischer Preistrends von Bitcoin. Jan 15, 2025 pm 08:14 PM

Bitcoin hat als Kryptowährung seit seiner Einführung erhebliche Marktvolatilität erlebt. Dieser Artikel bietet einen Überblick über den historischen Preis von Bitcoin seit seiner Geburt, um den Lesern zu helfen, seine Preistrends und Schlüsselmomente zu verstehen. Durch die Analyse der historischen Preisdaten von Bitcoin können wir die Einschätzung des Marktes über seinen Wert und die Faktoren, die seine Schwankungen beeinflussen, verstehen und eine Grundlage für zukünftige Investitionsentscheidungen schaffen.

Eine Liste der historischen Preise seit der Geburt von Bitcoin BTC Historical Price Trend Chart (neueste Zusammenfassung) Eine Liste der historischen Preise seit der Geburt von Bitcoin BTC Historical Price Trend Chart (neueste Zusammenfassung) Feb 11, 2025 pm 11:36 PM

Seit seiner Gründung im Jahr 2009 hat der Preis von Bitcoin im November 2021 auf 69.044,77 USD auf 69.044,77 USD gestiegen und im Dezember 2018 auf 3.191,22 USD gesunken. Ab Dezember 2024 hat der jüngste Preis 100.204 USD überschritten.

Der jüngste Preis für Bitcoin in den Jahren 2018-2024 USD Der jüngste Preis für Bitcoin in den Jahren 2018-2024 USD Feb 15, 2025 pm 07:12 PM

Echtzeit-Bitcoin-USD-Preis Faktoren, die den Bitcoin -Preis beeinflussen Indikatoren für die Vorhersage zukünftiger Bitcoin -Preise Hier finden Sie einige wichtige Informationen zum Preis von Bitcoin in den Jahren 2018-2024:

Wie kann man das Größensymbol durch CSS anpassen und es mit der Hintergrundfarbe einheitlich machen? Wie kann man das Größensymbol durch CSS anpassen und es mit der Hintergrundfarbe einheitlich machen? Apr 05, 2025 pm 02:30 PM

Die Methode zur Anpassung der Größe der Größe der Größe der Größe in CSS ist mit Hintergrundfarben einheitlich. In der täglichen Entwicklung begegnen wir häufig Situationen, in denen wir die Details der Benutzeroberfläche wie Anpassung anpassen müssen ...

Ist die H5-Seitenproduktion eine Front-End-Entwicklung? Ist die H5-Seitenproduktion eine Front-End-Entwicklung? Apr 05, 2025 pm 11:42 PM

Ja, die H5-Seitenproduktion ist eine wichtige Implementierungsmethode für die Front-End-Entwicklung, die Kerntechnologien wie HTML, CSS und JavaScript umfasst. Entwickler bauen dynamische und leistungsstarke H5 -Seiten auf, indem sie diese Technologien geschickt kombinieren, z. B. die Verwendung der & lt; canvas & gt; Tag, um Grafiken zu zeichnen oder JavaScript zu verwenden, um das Interaktionsverhalten zu steuern.

Der Text unter Flex -Layout wird weggelassen, aber der Behälter wird geöffnet? Wie löst ich es? Der Text unter Flex -Layout wird weggelassen, aber der Behälter wird geöffnet? Wie löst ich es? Apr 05, 2025 pm 11:00 PM

Das Problem der Containeröffnung aufgrund einer übermäßigen Auslassung von Text unter Flex -Layout und Lösungen werden verwendet ...

Wie verwendet ich das Clip-Pfad-Attribut von CSS, um den 45-Grad-Kurveneffekt des Segmenters zu erreichen? Wie verwendet ich das Clip-Pfad-Attribut von CSS, um den 45-Grad-Kurveneffekt des Segmenters zu erreichen? Apr 04, 2025 pm 11:45 PM

Wie kann man den 45-Grad-Kurveneffekt des Segmenters erreichen? Bei der Implementierung des Segmenters verwandeln Sie den rechten Rand in eine 45-Grad-Kurve, wenn Sie auf die linke Schaltfläche klicken, und der Punkt ...