목차
질문 내용
Solution
...但我需要单调递增的时间戳!
currenttimemillis
nanotime
问题
Java 긴 시간 창에 걸쳐 계산된 경과 시간이 System.currentTimeMillis와 System.nanoTime 사이에서 최대 100밀리초 이상 다른 이유는 무엇입니까?

긴 시간 창에 걸쳐 계산된 경과 시간이 System.currentTimeMillis와 System.nanoTime 사이에서 최대 100밀리초 이상 다른 이유는 무엇입니까?

Feb 09, 2024 am 10:24 AM
overflow

PHP Apple의 편집자가 큰 시간 창에서 계산된 경과 시간이 System.currentTimeMillis와 System.nanoTime 사이에 최대 100밀리초 이상 차이가 나는 이유를 설명합니다. 이 문제는 컴퓨터 시스템의 기본 메커니즘과 운영 체제의 스케줄링 방법과 관련이 있습니다. 경과 시간을 계산할 때 System.currentTimeMillis는 운영 체제에서 제공하는 벽시계 시간을 사용하는 반면 System.nanoTime은 CPU 시계 주기를 사용합니다. 운영 체제의 스케줄링 메커니즘과 하드웨어 시계의 비동기 특성으로 인해 이 두 가지 타이밍 방법으로 인해 시간 차이가 발생합니다. 구체적인 이유와 해결책은 다음 글에서 자세히 소개하겠습니다.

질문 내용

동일한 jvm에서 마이크로초 세차 정렬을 수행할 수 있는 ksuid를 만들려고 합니다. currenttimemillis는 밀리초 정밀도만 제공하므로 첫 번째 순간을 수집하려면 currenttimemillis()와 nanotime()을 함께 사용하는 것이 좋습니다. 나노타임 차이는 다음과 같습니다. 첫 번째 순간 이후 경과된 마이크로초 수와 두 번째 순간부터 시작하는 값으로 계산됩니다. 나노타임에서 계산된 경과 시간을 사용하고 이를 초기 순간 밀리초에 추가하면 jvm이 시작된 후 언제든지(모두 동일한 jvm 내에서) 마이크로초 정밀도로 에포크를 계산할 수 있습니다.

//초기 나노시간 및 현재 밀리리스의 정적 수집 最终长 inittimenanos = system.nanotime();最终长 inittimemillis = system.currenttimemillis();

//이제부터는 마이크로/나노초 정밀도의 현재시간이 필요할 때 나노시간에서 경과시간을 계산하여 초기화밀리초에 경과된 밀리초를 더하고 남은 경과시간은 마이크로초 정밀도의 시간이 됩니다

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

//jvm이 시작된 이후 타임스탬프 밀리초가 단조롭게 증가합니다(에포크, 에포크라고 부르지 않을 수도 있음) final 长计算当前时间millis = inittimemillis + elapsedmillisfromnanotime; final long nanosprecision = elapsednanos % 1000000; //나노타임의 추가 시간 정밀도

현재 시간에 근접하지만 동일한 jvm 내에서 생성 시간을 기준으로 정렬되도록 보장되는 단조 증가 ksuid를 생성하려면 이러한 값을 사용하는 것이 좋습니다. currenttimemillis는 단조 증가 타임스탬프 보장을 제공하지 않기 때문에 이 접근 방식을 사용하여 생성하는 것이 좋습니다. 대략적으로 실제 타임스탬프의 단조롭게 증가하는 타임스탬프입니다(에포크 시간에 윤초 조정이 이루어지지 않는 한 몇 밀리초씩 달라질 수 있음). 에포크(Epoch)와 나노타임(Nanotime)을 이용해 계산한 경과 시간은 수 밀리초 정도 차이가 날 것으로 예상됐으나 실제 차이는 매우 빈번하게 변했고, 아래에서 48시간 동안 테스트를 실행해보니 둘 사이 최대 150밀리초의 차이가 관찰됐다. 대부분의 경우 nanotime을 사용하여 계산한 경과 시간은 currenttimemillis를 사용하여 계산한 경과 시간보다 길며, 관찰된 시간의 범위는 -2밀리초에서 +150밀리초까지입니다.

final long elapsedmillis = system.currenttimemillis() - inittimemillis; //system.currenttimemillis()에서 경과된 시간(밀리초) 最终双方差millis = elapsedmillisfromnanotime - elapsedmillis; //경과 시간 차이

jvm 타이밍 보장에 대해 누락된 것이 있습니까? 단조롭게 증가하는 대략적인 타임스탬프를 계산하는 방법이 잘못되었습니까? (이것은 시스템에서 실제 시대로 사용되지 않으며 동일한 jvm 내에서 대략적인 타임스탬프 순간을 나타내는 uuid를 생성하는 데에만 사용됩니다.)

//테스트 수업

으아악

경과 시간 차이가 계속 변하는 이유는 무엇인가요? jvm이 1년 동안 지속적으로 실행되는 경우 기대할 수 있는 최대 분산은 얼마입니까(모든 jvm은 이에 대한 상한 또는 하한을 보장하고 Mac 및 Windows로 테스트했으며 Mac은 분산이 느리게 증가했으며 Windows는 훨씬 빨랐습니다)?

경과 시간은 10밀리초 미만으로 변동하고 변경 빈도는 더 낮을 것으로 예상됩니다. 그러나 실제 관찰은 분산이 계속 변하고 위아래로 변동하며 48시간 내에 최대 150밀리초가 관찰된다는 것입니다

Solution

한 가지 설명은 ntp를 기반으로 한 시간 번짐입니다. 보다 일반적으로 nanotime과 ctm은 완전히 다른 것을 측정하므로 혼합할 수 없습니다.

nanotime에는 임의의 0 지점이 있으므로(0의 나노타임을 얻는 것은 특별한 의미가 없음), 반환된 내용을 다른 나노타임 호출의 결과와 비교하는 것 외에는 호출할 필요가 없습니다. nanotime은 경과 시간을 추적합니다. 그게 전부입니다.

system.ctm은 시스템 시계를 가져옵니다. posix date 命令或在系统设置中编辑系统的时间设置,则不会影响 nanotime,但会更改 system.ctm를 사용하면 반환되는 내용입니다. ctm은 일반적으로 나노타임보다 훨씬 느립니다. ctm에는 1970년 1월 1일 자정(UTC)을 나타내는 잘 정의된 0도 있습니다.

질문: "현재 시간을 나노초 정밀도로 시스템 시계와 일치시키길 원합니다."는 jvm에서 불가능입니다.

时间涂抹是指某些网络时间守护程序注意到您的系统时钟略有偏差,并且不只是将系统时钟编辑到正确的时间,而是引入了涂抹:假设您比实时时间“提前”了 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);
  }
}
로그인 후 복사

这将返回当前时间,左移 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 类能够以纳秒为单位。

똑똑한 아이디어. 그러나 그것은 현실적이지 않습니다. 위에서 언급했듯이 currenttimemillisnanotime 不相关。最重要的是,currenttimemillis 的结果可能会因多种原因而有所不同。同时,nanotime 计数可能会随着主机的每次启动而变化,并且肯定不会对应于其他计算机上进行的任何 nanotime 호출됩니다.

예, 당신은 Java 사양이 당신이 가정하고 있는 것처럼 보이는 어떠한 보장도 하지 않는다는 사실을 무시하고 있습니다.

javadoc의 유일한 보장은 nanotime 是“高分辨率”,至少与 currenttimemillis이 좋다는 것입니다. 그리고 292의 종말을 언제 기대할 수 있는지 보장할 수 없습니다.

동시에 currenttimemillis는 움직이는 대상이며 앞으로 또는 뒤로 이동하여 언제든지 변경될 수 있습니다.

예측할 수 없습니다.

Java 사양에서는 그러한 보장을 하지 않습니다.

위 내용은 긴 시간 창에 걸쳐 계산된 경과 시간이 System.currentTimeMillis와 System.nanoTime 사이에서 최대 100밀리초 이상 다른 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25 : Myrise에서 모든 것을 잠금 해제하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

2009-2025년 탄생 이후 비트코인 ​​가격 BTC 역사적 가격에 대한 가장 완벽한 요약 2009-2025년 탄생 이후 비트코인 ​​가격 BTC 역사적 가격에 대한 가장 완벽한 요약 Jan 15, 2025 pm 08:11 PM

2009년 창립 이래 비트코인은 암호화폐 세계의 리더가 되었으며 가격은 큰 변동을 겪었습니다. 포괄적인 역사적 개요를 제공하기 위해 이 기사에서는 2009년부터 2025년까지의 비트코인 ​​가격 데이터를 수집하여 주요 시장 이벤트, 시장 정서 변화, 가격 변동에 영향을 미치는 중요한 요소를 다룹니다.

비트코인 탄생 이후의 역사적 가격 개요 비트코인의 역사적 가격 추세를 완벽하게 수집합니다. 비트코인 탄생 이후의 역사적 가격 개요 비트코인의 역사적 가격 추세를 완벽하게 수집합니다. Jan 15, 2025 pm 08:14 PM

암호화폐인 비트코인은 출시 이후 상당한 시장 변동성을 경험해 왔습니다. 이 기사에서는 독자들이 가격 추세와 주요 순간을 이해하는 데 도움이 되도록 탄생 이후 비트코인의 역사적 가격에 대한 개요를 제공합니다. 비트코인의 과거 가격 데이터를 분석함으로써 우리는 시장의 가치 평가, 변동에 영향을 미치는 요인을 이해하고 향후 투자 결정의 기초를 제공할 수 있습니다.

비트 코인 BTC 역사 가격 추세 차트의 탄생 이후의 역사적 가격 목록 (최신 요약) 비트 코인 BTC 역사 가격 추세 차트의 탄생 이후의 역사적 가격 목록 (최신 요약) Feb 11, 2025 pm 11:36 PM

Bitcoin의 Price는 2009 년에 창설 된 이래 2021 년 11 월에 69,044.77 달러로 상승하여 2018 년 12 월에 3,191.22 달러로 감소했습니다. 2024 년 12 월 현재 최신 가격은 $ 100,204를 초과했습니다.

2018-2024 USD의 Bitcoin의 최신 가격 2018-2024 USD의 Bitcoin의 최신 가격 Feb 15, 2025 pm 07:12 PM

실시간 비트 코인 USD 가격 비트 코인 가격에 영향을 미치는 요인 향후 비트 코인 가격을 예측하기위한 지표 다음은 2018-2024 년 비트 코인 가격에 대한 몇 가지 주요 정보입니다.

CSS를 통해 크기 조정 기호를 사용자 정의하고 배경색으로 균일하게 만드는 방법은 무엇입니까? CSS를 통해 크기 조정 기호를 사용자 정의하고 배경색으로 균일하게 만드는 방법은 무엇입니까? Apr 05, 2025 pm 02:30 PM

CSS에서 크기 조정 기호를 사용자 정의하는 방법은 배경색으로 통합됩니다. 매일 개발에서, 우리는 종종 조정과 같은 사용자 인터페이스 세부 정보를 사용자 정의 해야하는 상황을 발생시킵니다.

CSS의 클립 경로 속성을 사용하여 세그먼터의 45도 곡선 효과를 달성하는 방법은 무엇입니까? CSS의 클립 경로 속성을 사용하여 세그먼터의 45도 곡선 효과를 달성하는 방법은 무엇입니까? Apr 04, 2025 pm 11:45 PM

세그먼터의 45도 곡선 효과를 달성하는 방법은 무엇입니까? 세분화 장치를 구현하는 과정에서 왼쪽 버튼을 클릭 할 때 오른쪽 테두리를 45도 곡선으로 바꾸는 방법과 포인트 ...

H5 페이지 제작은 프론트 엔드 개발입니까? H5 페이지 제작은 프론트 엔드 개발입니까? Apr 05, 2025 pm 11:42 PM

예, H5 페이지 제작은 HTML, CSS 및 JavaScript와 같은 핵심 기술을 포함하는 프론트 엔드 개발을위한 중요한 구현 방법입니다. 개발자는 & lt; canvas & gt; 그래픽을 그리거나 상호 작용 동작을 제어하기 위해 JavaScript를 사용하는 태그.

Chatgpt 시대에는 기술 Q & A 커뮤니티가 어떻게 도전에 대응할 수 있습니까? Chatgpt 시대에는 기술 Q & A 커뮤니티가 어떻게 도전에 대응할 수 있습니까? Apr 01, 2025 pm 11:51 PM

Chatgpt 시대의 기술 Q & A 커뮤니티 : Segmentfault의 응답 전략 stackoverflow ...