关于Java 获取时间戳的方法

网友投稿 482 2022-08-03


关于Java 获取时间戳的方法

java有两个取时间戳的方法:System.currentTimeMillis() 和System.nanoTime(),它们的使用场景是有区别的,当前网上一些文章对于这两个方法的性能讨论存在一些片面的描述,本文希望能给出一个简单的最终答案。

System.currentTimeMillis() 存在性能问题?

答案是否定的。

这两个方法性能差异取决于操作系统。

Windows:

在 Windows 下,System.currentTimeMillis() 比System.nanoTime() 要快很多,这是因为 Windows 系统为前者提供的只是一个缓存变量,而后者则是实时的去硬件底层获取计数。

参考

所以如果你的生产环境是 Windows,请尽可能避免使用 System.nanoTime()。

linux:

在 Linux 下,两者的执行耗时相差不大,不论是单线程还是多线程。

不同的虚拟机实现会带来性能差异

如今的云主机主要有 Xen 和 KVM 两种实现方式,网上有文章发现HpVxn它们在取系统时间方面存在性能差异。

当我们的虚拟机用的是 Xen 时,取时间的耗时会是 KVM 的十倍以上。不过上文也提供了遇到此类问题该如何解决的方案。

需要写一个专门的类来提升 System.currentTimeMillis() 性能吗?

不需要。那属于画蛇添足。

我的测试代码

我的测试代码如下,没有任何依赖,可以直接用 javac 编译然后运行。读者有兴趣可以试试。

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 testing = test -> {

System.out.println("Single thread test:");

test.run();

System.out.println(THREAD_COUNT + " threads test:");

List 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);

}

}

因为我用的是 Windows,所以执行输出当中System.nanoTime() 明显非常慢。具体输出内容我就不放出来了,因为不具有参考价值,大多数生产环境用的是 Linux。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:JVM中判定对象需要回收的方法(java怎么判断对象是否可以被回收)
下一篇:Java实现PDF文件的分割与加密功能(java pdf拆分)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~