Java中有秒表吗?

145

Java中有计时器吗?
在谷歌上,我只找到了不起作用的计时器代码 - 它们总是返回0毫秒。

我找到的这段代码不起作用,而且我不知道为什么。

public class StopWatch {
  
  private long startTime = 0;
  private long stopTime = 0;
  private boolean running = false;
  
  
  public void start() {
    this.startTime = System.currentTimeMillis();
    this.running = true;
  }
  
  
  public void stop() {
    this.stopTime = System.currentTimeMillis();
    this.running = false;
  }
  
  
  //elaspsed time in milliseconds
  public long getElapsedTime() {
    long elapsed;
    if (running) {
      elapsed = (System.currentTimeMillis() - startTime);
    } else {
      elapsed = (stopTime - startTime);
    }
    return elapsed;
  }
  
  
  //elaspsed time in seconds
  public long getElapsedTimeSecs() {
    long elapsed;
    if (running) {
      elapsed = ((System.currentTimeMillis() - startTime) / 1000);
    } else {
      elapsed = ((stopTime - startTime) / 1000);
    }
    return elapsed;
  }
}

10
你如何确定它没有起作用?(也许你正在测量某些执行时间比System.currentTimeMillis()的精度更高的东西) - nos
5
请发布测试这个类的代码... - DXTR66
3
只想指出,这是《Java编程入门,综合版(第9版)》中的教科书问题之一。 - Sam
5
请勿在生产环境中使用currentTimeMillis(),因为它与系统日期/时间相关,并且不能保证单调递增(例如,您可能会获得负的经过时间)。用于测量时间请使用nanoTime()-它保证单调递增并且专门用于测量目的。请参见https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#nanoTime-- - Nikita Bosik
18个回答

2

试试这个

import java.awt.event.*;

import java.awt.*;

import javax.swing.*;

public class millis extends JFrame implements ActionListener, Runnable
    {

     private long startTime;
     private final static java.text.SimpleDateFormat timerFormat = new java.text.SimpleDateFormat("mm : ss.SSS");
     private final JButton startStopButton= new JButton("Start/stop");
     private Thread updater;
     private boolean isRunning= false;
     private final Runnable displayUpdater= new Runnable()
         {
         public void run()
             {
             displayElapsedTime(System.currentTimeMillis() - millis.this.startTime);
         }
     };
     public void actionPerformed(ActionEvent ae)
         {
         if(isRunning)
             {
             long elapsed= System.currentTimeMillis() - startTime;
             isRunning= false;
             try
                 {
                 updater.join();
                 // Wait for updater to finish
             }
             catch(InterruptedException ie) {}
             displayElapsedTime(elapsed);
             // Display the end-result
         }
         else
             {
             startTime= System.currentTimeMillis();
             isRunning= true;
             updater= new Thread(this);
             updater.start();
         }
     }
     private void displayElapsedTime(long elapsedTime)
         {
         startStopButton.setText(timerFormat.format(new java.util.Date(elapsedTime)));
     }
     public void run()
         {
         try
             {
             while(isRunning)
                 {
                 SwingUtilities.invokeAndWait(displayUpdater);
                 Thread.sleep(50);
             }
         }
         catch(java.lang.reflect.InvocationTargetException ite)
             {
             ite.printStackTrace(System.err);
             // Should never happen!
         }
         catch(InterruptedException ie) {}
         // Ignore and return!
     }
     public millis()
         {
         startStopButton.addActionListener(this);
         getContentPane().add(startStopButton);
         setSize(100,50);
         setVisible(true);
     }
     public static void main(String[] arg)
         {
         new Stopwatch().addWindowListener(new WindowAdapter()
             {
             public void windowClosing(WindowEvent e)
                 {
                 System.exit(0);
             }
         });
         millis s=new millis();
         s.run();
     }
}

1
如其他地方所述,currentTimeMillis()与系统日期/时间相关,并不能保证单调性(例如,您可能会得到负的经过时间)。 - oligofren

2

一个简单易用的秒表类:

import java.time.Duration;
import java.time.Instant;

public class StopWatch {

    Instant startTime, endTime;
    Duration duration;
    boolean isRunning = false;

    public void start() {
        if (isRunning) {
            throw new RuntimeException("Stopwatch is already running.");
        }
        this.isRunning = true;
        startTime = Instant.now();
    }

    public Duration stop() {
        this.endTime = Instant.now();
        if (!isRunning) {
            throw new RuntimeException("Stopwatch has not been started yet");
        }
        isRunning = false;
        Duration result = Duration.between(startTime, endTime);
        if (this.duration == null) {
            this.duration = result;
        } else {
            this.duration = duration.plus(result);
        }

        return this.getElapsedTime();
    }

    public Duration getElapsedTime() {
        return this.duration;
    }

    public void reset() {
        if (this.isRunning) {
            this.stop();
        }
        this.duration = null;
    }
}

使用方法:

StopWatch sw = new StopWatch();
sw.start();
    // doWork()
sw.stop();
System.out.println( sw.getElapsedTime().toMillis() + "ms");

2

试一试。

public class StopWatch { 

      private long startTime = 0;
      private long stopTime = 0;

      public StopWatch()
      {
            startTime = System.currentTimeMillis();
      }

      public void start() {
        startTime = System.currentTimeMillis();
      }

      public void stop() {
        stopTime = System.currentTimeMillis();
        System.out.println("StopWatch: " + getElapsedTime() + " milliseconds.");
        System.out.println("StopWatch: " + getElapsedTimeSecs() + " seconds.");
      }

      /**
       * @param process_name
       */
      public void stop(String process_name) {
            stopTime = System.currentTimeMillis();
            System.out.println(process_name + " StopWatch: " + getElapsedTime() + " milliseconds.");
            System.out.println(process_name + " StopWatch: " + getElapsedTimeSecs() + " seconds.");
      }      

      //elaspsed time in milliseconds
      public long getElapsedTime() {
          return stopTime - startTime;
      }

      //elaspsed time in seconds
      public double getElapsedTimeSecs() {
        double elapsed;
          elapsed = ((double)(stopTime - startTime)) / 1000;
        return elapsed;
      }
} 

使用方法:

StopWatch watch = new StopWatch();
// do something
watch.stop();

控制台:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.

尽管这可能或可能不是问题所要求的,但您的答案帮助了我解决了我的问题。谢谢。 - Toiletduck
1
currentTimeMillis() 是与系统日期/时间相关的,不保证单调递增(例如,可能会得到负的经过时间)。 - oligofren
1
如果你决定自己构建,请使用 System.nanoTime() 来始终获得正确的结果。 - oligofren

2

Performetrics 提供了一个方便的秒表类(Stopwatch class),可以按你所需的方式度量墙钟时间,还可以测量 CPU 时间(用户时间和系统时间)。

这个类很小,而且免费,你可以从 Maven Central 下载。

更多信息和示例请访问这里:https://obvj.net/performetrics

Stopwatch sw = new Stopwatch();
sw.start();

// Your code

sw.stop();
sw.printStatistics(System.out);

// Sample output:
// +-----------------+----------------------+--------------+
// | Counter         |         Elapsed time | Time unit    |
// +-----------------+----------------------+--------------+
// | Wall clock time |             85605718 | nanoseconds  |
// | CPU time        |             78000500 | nanoseconds  |
// | User time       |             62400400 | nanoseconds  |
// | System time     |             15600100 | nanoseconds  |
// +-----------------+----------------------+--------------+

你可以将度量标准转换为任何时间单位(纳秒,毫秒,秒等)。
PS:我是这个工具的作者。

1

请试试这个。

Java秒表完整解决方案

在这里,您将获得一个完整的解决方案。

以下是来自上述链接解决方案的一小段:

您可以创建像下面代码一样的类,并在想要测量所需时间的代码部分之前和之后使用此类的开始和停止方法。

public class Stopwatch{
  private long startTime;
  private long stopTime;

  /**
   starting the stop watch.
  */
  public void start(){
        startTime = System.nanoTime();
  }

  /**
   stopping the stop watch.
  */
  public void stop()
  {     stopTime = System.nanoTime(); }

  /**
  elapsed time in nanoseconds.
  */
  public long time(){
        return (stopTime - startTime);
  }

  public String toString(){
      return "elapsed time: " + time() + " nanoseconds.";
  }

}

谢谢。

1
虽然这个链接可能回答了问题,但最好在此处包含答案的基本部分并提供参考链接。仅有链接的答案如果链接页面发生更改可能会失效。 - AS Mackay
感谢 @ASMackay 的建议。我完全同意你的观点。 - Sukriti Sarkar

1

0

我创建了一个秒表,里面包含你可能需要的一切。

我甚至进行了文档化

而且,我还编译了它以实现更快的使用。

这里是一个例子:

//...
  //For demo only!
  public static void main(String[]a){
    final Stopwatch stopwatch=new Stopwatch();
    stopwatch.start();
    try{
      java.lang.Thread.sleep(1000);
    }catch(Exception e){}
    stopwatch.split();
    System.out.println("Time elapsed in nanoseconds: "+stopwatch.getTimeElapsed());
    System.out.println("Time elapsed in milliseconds: "+stopwatch.getTimeElapsed(Stopwatch.millis));
    System.out.println("Time elapsed in seconds: "+stopwatch.getTimeElapsed(Stopwatch.seconds));
    try{
      java.lang.Thread.sleep(1000);
    }catch(Exception e){}
    stopwatch.split();
    final long[][] laps=stopwatch.getLaps();
    for(long[] lap:laps){
      System.out.println(java.util.Arrays.toString(lap));
    }
  }
//...

这不是为了宣传,制作此工具 是为了帮助人们不再浪费时间在编程课程中!


0

试试这个...

import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;

public class StopwatchTest {
     
    public static void main(String[] args) throws Exception {
        Stopwatch stopwatch = Stopwatch.createStarted();
        Thread.sleep(1000 * 60);
        stopwatch.stop(); // optional
        long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
        System.out.println("Time in milliseconds "+millis);
        System.out.println("that took: " + stopwatch);
    }
}

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