HOWTO · Java

在 Java 中制作秒表

它描述了如何使用 Java 中的不同方法制作秒表

本页内容

我们可以使用我们将在下面看到的几种方法来获取 Java 中特定任务的经过时间。当任务对时间至关重要时,需要一个 java 秒表,我们想知道长时间运行的任务(如计算斐波那契数列)所花费的时间。

Java 中的秒表使用 System.nanoTime()

我们希望保持秒表时间尽可能准确,为此,我们使用 System.nanotTime() 类返回纳秒值,该值是系统计时器的最精确值。

在程序中,我们创建了两个类,Stopwatch1Stopwatch。在 Stopwatch1 两种启动和停止秒表的方法中,start() 使用 System.nanoTime() 用当前的纳秒初始化 stopWatchStartTime 并设置 stopWatchRunning 的值(检查秒表是否在运行)为

stop() 初始化 stopWatchStopTime 并将 stopWatchRunning 设置为 false。然后,我们可以使用四个函数来计算以毫秒、秒、分钟和小时为单位的总经过时间。每个方法都有一个名为 elapsedTime 的局部变量,它存储的值是 System.nanoTime() 的值减去 stopWatchStartTime 如果秒表正在运行并且它没有运行,那么我们执行 stopWatchStopTime - stopWatchStartTime

现在,由于每个函数中 elapsedTime 的值以纳秒为单位,我们通过将 elapsedTime 除以它持有的纳秒来将其值转换为不同的时间单位。

Stopwatch 类中,我们创建了一个 Stopwatch1 的对象并调用了 start() 方法。然后我们调用使用递归方法计算斐波那契数列的方法,最后调用 stop() 函数。start()stop() 函数之间的时间是输出中显示的经过时间。

import java.math.BigInteger;

class Stopwatch1 {
  private final long nanoSecondsPerMillisecond = 1000000;
  private final long nanoSecondsPerSecond = 1000000000;
  private final long nanoSecondsPerMinute = 60000000000L;
  private final long nanoSecondsPerHour = 3600000000000L;

  private long stopWatchStartTime = 0;
  private long stopWatchStopTime = 0;
  private boolean stopWatchRunning = false;

  public void start() {
    this.stopWatchStartTime = System.nanoTime();
    this.stopWatchRunning = true;
  }

  public void stop() {
    this.stopWatchStopTime = System.nanoTime();
    this.stopWatchRunning = false;
  }

  public long getElapsedMilliseconds() {
    long elapsedTime;

    if (stopWatchRunning)
      elapsedTime = (System.nanoTime() - stopWatchStartTime);
    else
      elapsedTime = (stopWatchStopTime - stopWatchStartTime);

    return elapsedTime / nanoSecondsPerMillisecond;
  }

  public long getElapsedSeconds() {
    long elapsedTime;

    if (stopWatchRunning)
      elapsedTime = (System.nanoTime() - stopWatchStartTime);
    else
      elapsedTime = (stopWatchStopTime - stopWatchStartTime);

    return elapsedTime / nanoSecondsPerSecond;
  }

  public long getElapsedMinutes() {
    long elapsedTime;
    if (stopWatchRunning)
      elapsedTime = (System.nanoTime() - stopWatchStartTime);
    else
      elapsedTime = (stopWatchStopTime - stopWatchStartTime);

    return elapsedTime / nanoSecondsPerMinute;
  }

  public long getElapsedHours() {
    long elapsedTime;
    if (stopWatchRunning)
      elapsedTime = (System.nanoTime() - stopWatchStartTime);
    else
      elapsedTime = (stopWatchStopTime - stopWatchStartTime);

    return elapsedTime / nanoSecondsPerHour;
  }
}

public class Stopwatch {
  public static void main(String[] args) {
    Stopwatch1 stopwatch1 = new Stopwatch1();
    stopwatch1.start();
    Fibonacci(45);
    stopwatch1.stop();

    System.out.println("Elapsed time in milliseconds: " + stopwatch1.getElapsedMilliseconds());

    System.out.println("Elapsed time in seconds: " + stopwatch1.getElapsedSeconds());

    System.out.println("Elapsed time in minutes: " + stopwatch1.getElapsedMinutes());

    System.out.println("Elapsed time in hours: " + stopwatch1.getElapsedHours());
  }

  private static BigInteger Fibonacci(int n) {
    if (n < 2)
      return BigInteger.ONE;
    else
      return Fibonacci(n - 1).add(Fibonacci(n - 2));
  }
}

输出:

Elapsed time in milliseconds: 31161
Elapsed time in seconds: 31
Elapsed time in minutes: 0
Elapsed time in hours: 0

Java 中使用 Apache Commons Lang 的秒表

对于此示例,我们使用 Apache Commons 库。以下是将其包含在我们的项目中的依赖项。

 <dependency>
     <groupId>org.apache.commons</groupId>
     <artifactId>commons-lang3</artifactId>
     <version>3.11</version>
 </dependency>

我们创建库附带的 StopWatchstopWatch 的对象,然后调用 start() 函数。启动秒表后,我们调用 Fibonacci() 函数,然后使用 stop() 停止计时。现在要获取经过的时间,我们调用 stopWatch.getTime() 返回经过的时间,在 getTime() 中,我们可以传递不同的时间单位。

import java.math.BigInteger;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.time.StopWatch;

public class Stopwatch {
  public static void main(String[] args) {
    StopWatch stopWatch = new StopWatch();

    stopWatch.start();
    Fibonacci(40);
    stopWatch.stop();

    System.out.println(
        "Get elapsed time in milliseconds: " + stopWatch.getTime(TimeUnit.MILLISECONDS));
    System.out.println("Get elapsed time in seconds: " + stopWatch.getTime(TimeUnit.SECONDS));
    System.out.println("Get elapsed time in minutes: " + stopWatch.getTime(TimeUnit.MINUTES));
    System.out.println("Get elapsed time in hours: " + stopWatch.getTime(TimeUnit.HOURS));
  }

  private static BigInteger Fibonacci(int n) {
    if (n < 2)
      return BigInteger.ONE;
    else
      return Fibonacci(n - 1).add(Fibonacci(n - 2));
  }
}

输出:

Get elapsed time in milliseconds: 3483
Get elapsed time in seconds: 3
Get elapsed time in minutes: 0
Get elapsed time in hours: 0

在 Java 中使用 Instant 的秒表

Instantjava.time 包的一部分。它从系统时钟返回当前时刻。我们使用 Instant.now() 的两个即时值第一个是在执行 Fibonacci() 之前,一个是在执行之后。然后我们使用 Duration.between() 计算两个值之间的差异,其中我们传递 instatStartedinstantStopped 值,返回一个 Duration,我们可以将其转换为不同的时间单位,例如 toMillis() 毫秒,toSeconds() 表示秒,分钟表示我们使用 toMinutes()

import java.math.BigInteger;
import java.time.Duration;
import java.time.Instant;

public class Stopwatch {
  public static void main(String[] args) {
    Instant instantStarted = Instant.now();
    Fibonacci(40);
    Instant instantStopped = Instant.now();

    Duration durationBetween = Duration.between(instantStarted, instantStopped);

    System.out.println("Get elapsed time in milliseconds: " + durationBetween.toMillis());
    System.out.println("Get elapsed time in seconds: " + durationBetween.toSeconds());
    System.out.println("Get elapsed time in minutes: " + durationBetween.toMinutes());
  }

  private static BigInteger Fibonacci(int n) {
    if (n < 2)
      return BigInteger.ONE;
    else
      return Fibonacci(n - 1).add(Fibonacci(n - 2));
  }
}

输出:

Get elapsed time in milliseconds: 3510
Get elapsed time in seconds: 3
Get elapsed time in minutes: 0