關(guān)于Java?獲取時(shí)間戳的方法
Java有兩個(gè)取時(shí)間戳的方法:System.currentTimeMillis() 和System.nanoTime(),它們的使用場景是有區(qū)別的,當(dāng)前網(wǎng)上一些文章對于這兩個(gè)方法的性能討論存在一些片面的描述,本文希望能給出一個(gè)簡單的最終答案。
System.currentTimeMillis() 存在性能問題?
答案是否定的。
這兩個(gè)方法性能差異取決于操作系統(tǒng)。
Windows:
在 Windows 下,System.currentTimeMillis() 比System.nanoTime() 要快很多,這是因?yàn)?Windows 系統(tǒng)為前者提供的只是一個(gè)緩存變量,而后者則是實(shí)時(shí)的去硬件底層獲取計(jì)數(shù)。
所以如果你的生產(chǎn)環(huán)境是 Windows,請盡可能避免使用 System.nanoTime()。
Linux:
在 Linux 下,兩者的執(zhí)行耗時(shí)相差不大,不論是單線程還是多線程。
不同的虛擬機(jī)實(shí)現(xiàn)會(huì)帶來性能差異
如今的云主機(jī)主要有 Xen 和 KVM 兩種實(shí)現(xiàn)方式,網(wǎng)上有文章發(fā)現(xiàn)它們在取系統(tǒng)時(shí)間方面存在性能差異。
當(dāng)我們的虛擬機(jī)用的是 Xen 時(shí),取時(shí)間的耗時(shí)會(huì)是 KVM 的十倍以上。不過上文也提供了遇到此類問題該如何解決的方案。
需要寫一個(gè)專門的類來提升 System.currentTimeMillis() 性能嗎?
不需要。那屬于畫蛇添足。
我的測試代碼
我的測試代碼如下,沒有任何依賴,可以直接用 javac 編譯然后運(yùn)行。讀者有興趣可以試試。
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class TimePerformance {
public static final int LOOP_COUNT = 9999999;
public static final int THREAD_COUNT = 30;
public static void main(String[] args) {
Runnable millisTest = () -> {
long start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; i++) {
System.currentTimeMillis();
}
long end = System.currentTimeMillis();
System.out.printf("%s : %f ns per call\n",
Thread.currentThread().getName(), ((double)end - start) * 1000000 / LOOP_COUNT);
};
Runnable nanoTest = () -> {
long start = System.currentTimeMillis();
for (int i = 0; i < LOOP_COUNT; i++) {
System.nanoTime();
}
long end = System.currentTimeMillis();
System.out.printf("%s : %f ns per call\n",
Thread.currentThread().getName(), ((double)end - start) * 1000000 / LOOP_COUNT);
};
Consumer<Runnable> testing = test -> {
System.out.println("Single thread test:");
test.run();
System.out.println(THREAD_COUNT + " threads test:");
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < THREAD_COUNT; i++) {
Thread t = new Thread(test);
t.start();
threads.add(t);
}
// Wait for all threads to finish
threads.forEach(thread -> {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
};
System.out.println(" Test System.nanoTime()");
testing.accept(nanoTest);
System.out.println(" Test System.currentTimeMillis()");
testing.accept(millisTest);
}
}因?yàn)槲矣玫氖?Windows,所以執(zhí)行輸出當(dāng)中System.nanoTime() 明顯非常慢。具體輸出內(nèi)容我就不放出來了,因?yàn)椴痪哂袇⒖純r(jià)值,大多數(shù)生產(chǎn)環(huán)境用的是 Linux。
到此這篇關(guān)于關(guān)于Java 獲取時(shí)間戳的方法的文章就介紹到這了,更多相關(guān)Java 獲取時(shí)間戳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaWeb dbutils執(zhí)行sql命令并遍歷結(jié)果集時(shí)不能查到內(nèi)容的原因分析
這篇文章主要介紹了JavaWeb dbutils執(zhí)行sql命令并遍歷結(jié)果集時(shí)不能查到內(nèi)容的原因分析及簡單處理方法,文中給大家介紹了javaweb中dbutils的使用,需要的朋友可以參考下2017-12-12
HashMap方法之Map.getOrDefault()解讀及案例
這篇文章主要介紹了HashMap方法之Map.getOrDefault()解讀及案例,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
關(guān)于Java使用Http輕量級請求庫Unirest的方法
這篇文章主要介紹了關(guān)于Java使用Http輕量級請求庫Unirest的方法,Unirest 是一個(gè)輕量級的 HTTP 請求庫,可發(fā)起 GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS 請求,支持 Node、Ruby、Java、PHP、Python、Objective-C、.NET 等多種語言,需要的朋友可以參考下2023-08-08
使用maven方式創(chuàng)建springboot項(xiàng)目的方式
使用Spring Initializr創(chuàng)建spring boot項(xiàng)目,因?yàn)橥饩W(wǎng)問題導(dǎo)致很難成功,所以只能使用maven方式,這里介紹下使用maven方式創(chuàng)建springboot項(xiàng)目的方法,感興趣的朋友一起看看吧2022-09-09
java搭建一個(gè)Socket服務(wù)器響應(yīng)多用戶訪問
本篇文章主要介紹了java搭建一個(gè)Socket服務(wù)器響應(yīng)多用戶訪問,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02

