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