0
点赞
收藏
分享

微信扫一扫

关于Java获取时间戳的方法

路西法阁下 2022-03-12 阅读 48

Java有两个取时间戳的方法:System.currentTimeMillis() 和 System.nanoTime(),它们的使用场景是有区别的。

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


答案是否定的。

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

Windows:

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

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

Linux:

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

# 不同的虚拟机实现会带来性能差异
如今的云主机主要有 Xen 和 KVM 两种实现方式。

当你的虚拟机用的是 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<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);

    }

}

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

举报

相关推荐

0 条评论