在Java中,获取系统时间的最快方法是什么?

9
我正在开发一个系统,经常使用系统时间,因为需要使用Delayed接口。
如何更快地获取系统时间?
目前,每次需要获取时间时,我都使用Calendar.getInstance().getTimeInMillis(),但我不知道是否有更快的方法。

你在哪里使用time millis和DelayQueue? - Bozho
我表达不够清晰,我的意思是只在实现Delayed接口的类中使用getDelay()方法。 - Renato Dinhani
@Renato,Calendar.getInstance() 和 new Date() 都使用 System.currentTimeMillis(),但是 Calendar 明显比较慢。 - Peter Lawrey
7个回答

21

System.currentTimeMillis()
"返回当前时间的毫秒数".
使用此方法可获取实际系统时间。

System.nanoTime().
"该方法返回自某个固定且任意的起始时间以来经过的纳秒数"
如果你需要测量时间间隔或事件,则可以使用此方法。


2
请注意,这两种方法具有不同的特点,您应选择适合您需要的方法。 - Thorbjørn Ravn Andersen
据我所知,DelayQueue使用TimeUnit.NANOSECONDS来进行时间计算,因此在这种情况下,也许System.nanoTime()更加适合,以避免在getDelay()方法中进行单位转换。 - Renato Dinhani
你可以使用任何一个单位,所以都可以。nanoTime更精准。 - Bozho
1
有人进行过基准测试或者有一些分析证据表明System.currentTimeMillis()比Calendar.getInstance().getTimeInMillis()更快吗? - robguinness
1
即使它不是,当你可以直接从系统中获取毫秒时,你也不应该创建一个新实例来获取。 :) - Bozho
在大多数实现中,“固定但任意”的起点是什么意思? - John Dvorak

5

System.currentTimeMillis()在以下测试用例中最快

public class ClassTest
{
    @Test
    public void testSystemCurrentTime()
    {
        final Stopwatch stopwatch = Stopwatch.createStarted();
        for (int i = 0; i < 1_00_000; i++)
        {
            System.currentTimeMillis();
        }
        stopwatch.stop();
        System.out.println("System.currentTimeMillis(): " + stopwatch);
    }

    @Test
    public void testDateTime()
    {
        final Stopwatch stopwatch = Stopwatch.createStarted();
        for (int i = 0; i < 1_00_000; i++)
        {
            (new Date()).getTime();
        }
        stopwatch.stop();
        System.out.println("(new Date()).getTime(): " + stopwatch);
    }

    @Test
    public void testCalendarTime()
    {
        final Stopwatch stopwatch = Stopwatch.createStarted();
        for (int i = 0; i < 1_00_000; i++)
        {
            Calendar.getInstance().getTimeInMillis();
        }
        stopwatch.stop();
        System.out.println("Calendar.getInstance().getTimeInMillis(): " + stopwatch);
    }

    @Test
    public void testInstantNow()
    {
        final Stopwatch stopwatch = Stopwatch.createStarted();
        for (int i = 0; i < 1_00_000; i++)
        {
            Instant.now();
        }
        stopwatch.stop();
        System.out.println("Instant.now(): " + stopwatch);
    }
}

输出:

(new Date()).getTime(): 36.89 ms
Calendar.getInstance().getTimeInMillis(): 448.0 ms
Instant.now(): 34.13 ms
System.currentTimeMillis(): 10.28 ms

但是,

Instant.now() 很快且更简单,同时还提供其他实用工具,例如 Instant.now().getEpochSecond();,Instant.now().getNano();, Instant.now().compareTo(otherInstant); 等等。


这是99.9%情况下的推荐方式。虽然可能不是最快的(我没有进行测量),但清晰度至关重要,而不是速度。 - Ole V.V.
1
@craigcaulfield 我想知道为什么这个回答没有解答问题。他的回答只需要一些细节来说明为什么它是最快的。 - jizhihaoSAMA
我已经提出了我的建议,并将提供统计数据。 - parthivrshah

4
简而言之,System.currentTimeMillis() 更快。
@Test
public void testSystemCurrentTime() {
    final Stopwatch stopwatch = Stopwatch.createStarted();
    for (int i = 0; i < 1_00_000; i++) {
        System.currentTimeMillis();
    }
    stopwatch.stop();
    System.out.println("System.currentTimeMillis(): " + stopwatch);
}

@Test
public void testDateTime() {
    final Stopwatch stopwatch = Stopwatch.createStarted();
    for (int i = 0; i < 1_00_000; i++) {
        (new Date()).getTime();
    }
    stopwatch.stop();
    System.out.println("(new Date()).getTime(): " + stopwatch);
}

@Test
public void testCalendarTime() {
    final Stopwatch stopwatch = Stopwatch.createStarted();
    for (int i = 0; i < 1_00_000; i++) {
        Calendar.getInstance().getTimeInMillis();
    }
    stopwatch.stop();
    System.out.println("Calendar.getInstance().getTimeInMillis(): " + stopwatch);
}

我运行了上述测试用例,发现以下结果:
System.currentTimeMillis(): 5.208 ms    (new Date()).getTime(): 19.57 ms    Calendar.getInstance().getTimeInMillis(): 148.2 ms
System.currentTimeMillis(): 4.685 ms    (new Date()).getTime(): 11.53 ms    Calendar.getInstance().getTimeInMillis(): 122.6 ms
System.currentTimeMillis(): 4.734 ms    (new Date()).getTime(): 11.66 ms    Calendar.getInstance().getTimeInMillis(): 131.5 ms
System.currentTimeMillis(): 4.018 ms    (new Date()).getTime(): 19.33 ms    Calendar.getInstance().getTimeInMillis(): 127.6 ms
System.currentTimeMillis(): 5.474 ms    (new Date()).getTime(): 16.74 ms    Calendar.getInstance().getTimeInMillis(): 113.6 ms
System.currentTimeMillis(): 3.871 ms    (new Date()).getTime(): 14.46 ms    Calendar.getInstance().getTimeInMillis(): 120.5 ms
System.currentTimeMillis(): 8.223 ms    (new Date()).getTime(): 11.65 ms    Calendar.getInstance().getTimeInMillis(): 173.8 ms
System.currentTimeMillis(): 4.611 ms    (new Date()).getTime(): 9.978 ms    Calendar.getInstance().getTimeInMillis(): 117.9 ms
System.currentTimeMillis(): 3.794 ms    (new Date()).getTime(): 11.33 ms    Calendar.getInstance().getTimeInMillis(): 89.79 ms
System.currentTimeMillis(): 4.298 ms    (new Date()).getTime(): 12.37 ms    Calendar.getInstance().getTimeInMillis(): 123.8 ms

我希望您能从中受益。

1
针对大量请求,我认为应该有一个线程负责更新当前系统时间,避免每个线程独立进行。

1
真的,但我见过的所有操作系统都倾向于为您完成此操作。 - Rhumborl

0

System.currentTimeMillis() 可能是答案。


0
System.currentTimeMillis 

简单的答案就是这样


0

long timeMilliSec = System.currentTimeMillis();

long timeMilliSec = System.currentTimeMillis();


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接