Lendo o livro “Designing Data-Intensive Applications” aprendi algo muito util em Java. Sabia que System.currentTimeMillis()
e System.nanoTime()
são duas funcionalidades completamente diferente?
Para entender isso tem que se entender o conceito de Monotonic e Time-of-Day Clocks.
Clock é um sistema independente dentro de qualquer máquina que alimenta um contador independente da CPU. Tem um tick que incrementa esse contador e esse contador é usado para calcular a data.
Data é o número segundos/milissegundos desde do Epoch, que é 1º de janeiro de 1970 00:00:00.
Dá uma lida na documentação do GNU sobre a procedimento clock_gettime. Observa os parâmetros, vê que são dois clocks diferentes?
No CLOCK_REALTIME
, vai retornar um contador que é sempre atualizado pelo Sistema Operacional usando o servidor NTP.
No CLOCK_MONOTONIC
temos um contador monotonico, isso signitica que não vai ser atualizado pelo NTP.
Quais as implicações disso?
Sempre que você for usar o clock para pegar a data atual, use CLOCK_REALTIME
. Ele estará mais próximo da verdade (observer que ele tem um erro).
Sempre que você for calcular tempos de execução, use CLOCK_MONOTONIC
. Ele dará o real tempo de execução.
Em Java o System.currentTimeMillis()
usa o CLOCK_REALTIME
e o System.nanoTime()
usa o CLOCK_MONOTONIC
.
Isso porque o real time não tem tanta resolução, tem que se descontar a latência da rede entre o seu computador e o servidor NTP.
Imagina o caso abaixo:
long startTime = System.currentTimeMillis();
// ... código ...
long elapsedMillis = System.currentTimeMillis() - startTime;
Durante a execução o SO pode ter atualizado o clock e o elapsedMillis pode até ser negativo.
Já o código abaixo, temos a certeza que não foi atualizado.
long startTime = System.nanoTime();
// ... código ...
long elapsedNanos = System.nanoTime() - startTime;
E se eu quiser o tempo real universal? Acho que Einstein se entristece com essa pergunta, mas blz!
O Google tem uma API chamada TrueTime, que vai retornar a data baseada em vários servidores NTP e um intervalo de erro. Toda medida tem erro no mundo… Aceite!
Mas o TrueTime só é útil em caso de resolução de conflitos de concorrência complexos.
Ainda não achei uma API do TrueTime para Java (só para Android). Também nunca precisei. 😉
Lendo o livro "Designing Data-Intensive Applications" aprendi algo muito util em @Java.
— dev-roadmap (@dev_roadmap) October 7, 2021
Sabia que System.currentTimeMillis() e System.nanoTime() são duas funcionalidades completamente diferente?
Conclusão
Se você quer a data, use System.currentTimeMillis()
. Se você quer pegar o timestamp inicial para calcultar um tempo de execução, use System.nanoTime()
. É mais confiável.