Có đồng hồ bấm giờ trong Java không?


107

Có đồng hồ bấm giờ trong Java không? Trên google, tôi chỉ tìm thấy mã của đồng hồ bấm giờ không hoạt động - chúng luôn trả về 0 mili giây.

Mã này mà tôi tìm thấy không hoạt động nhưng tôi không hiểu tại sao.

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
Và làm thế nào để bạn xác định nó không hoạt động? (có lẽ bạn đang đo lường thứ gì đó cần ít thời gian hơn để thực thi so với độ chính xác của System.currentTimeMillis ())
nos

5
Xin vui lòng gửi mã như thế nào bạn đang thử nghiệm lớp này ...
DXTR66

2
Chỉ muốn lưu ý rằng đây là một trong những câu hỏi sách giáo khoa trong "Giới thiệu về Lập trình Java, Phiên bản Toàn diện (Phiên bản thứ 9)".
Sam

2
Vui lòng không sử dụng currentTimeMillis()cho sản xuất, vì nó bị ràng buộc với ngày / giờ hệ thống và không được đảm bảo là đơn điệu (ví dụ: bạn có thể nhận được thời gian đã trôi qua âm). Để đo thời gian sử dụng nanoTime()- nó được đảm bảo là đơn điệu và được thiết kế chính xác cho mục đích đo. Xem docs.oracle.com/javase/8/docs/api/java/lang/…
Nikita Bosik 20/02/18

Câu trả lời:



90

Sử dụng lớp học của GuavaStopwatch .

Một đối tượng đo thời gian đã trôi qua tính bằng nano giây. Sẽ rất hữu ích khi đo thời gian đã trôi qua bằng cách sử dụng lớp này thay vì các cuộc gọi trực tiếp đến System.nanoTime()vì một số lý do:

  • Nguồn thời gian thay thế có thể được thay thế vì lý do thử nghiệm hoặc hiệu suất.
  • Theo tài liệu của nanoTime, giá trị trả về không có ý nghĩa tuyệt đối và chỉ có thể được hiểu là liên quan đến dấu thời gian khác được nanoTime trả về vào một thời điểm khác. Đồng hồ bấm giờ là một sự trừu tượng hiệu quả hơn vì nó chỉ hiển thị những giá trị tương đối này, không phải những giá trị tuyệt đối.
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional

long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);

log.info("that took: " + stopwatch); // formatted string like "12.3 ms"

2
ổi đồng hồ bấm giờ là mất tích getStartTime(), apache là mất tích isRunning()ahhhh
Để Kra

3
@ToKra Bạn sẽ làm gì với thời gian bắt đầu? Vì đây là thời gian nano, bạn không thể sử dụng nó cho bất cứ điều gì có ý nghĩa, như được mô tả trong tài liệu.
Trejkaz

1
Bây giờ bạn sử dụng điều này để lấy mili giây: long stopWatch = stopWatch.elapsed (TimeUnit.MILLISECONDS);
PHPGuru 14/03/18

Đó là phiên bản ổi nào? Tôi đã sử dụng 1.8 và nó không tìm thấy lớp Đồng hồ bấm giờ
Laser Infinite

58

Bây giờ bạn có thể thử một cái gì đó như:

Instant starts = Instant.now();
Thread.sleep(10);
Instant ends = Instant.now();
System.out.println(Duration.between(starts, ends));

Đầu ra ở ISO 8601.


1
Nhanh chóng và dễ dàng, cảm ơn bạn rất nhiều! Giúp theo dõi thời lượng tác vụ ngay từ đầu.
ndm13

Điều gì sẽ xảy ra nếu bạn thay đổi thời gian hệ thống trong khi ngủ?
Peteter

1
@Peteter là một ví dụ duy nhất. Nếu bạn đang sử dụng hộp linux, bạn phải xử lý đồng hồ phần cứng và đồng hồ được quản lý hạt nhân. Nếu bạn thay đổi đồng hồ phần cứng, không có đồng hồ nào sẽ bị ảnh hưởng nhưng trong đồng hồ được quản lý hạt nhân, bạn sẽ gặp rắc rối: Instant.now () lấy thời gian hệ thống và sẽ hiển thị khoảng thời gian sai.
Valtoni Boaventura

Tôi thậm chí không biết nó hoạt động trên Android. Điều cần biết :)
Valtoni Boaventura

Chúng tôi không quên java.time.Instant là không thay đổi và chủ đề an toàn :)
Amos Kosgei

38

Spring cung cấp một org.springframework.util.StopWatchClass thanh lịch (mô-đun lõi lò xo).

StopWatch stopWatch = new StopWatch();
stopWatch.start();
     // Do something
stopWatch.stop();
     System.out.println(stopWatch.getTotalTimeMillis());

8

Sử dụng System.currentTimeMillis()để lấy thời gian bắt đầu và thời gian kết thúc và tính toán sự khác biệt.

class TimeTest1 {
  public static void main(String[] args) {

    long startTime = System.currentTimeMillis();

    long total = 0;
    for (int i = 0; i < 10000000; i++) {
      total += i;
    }

    long stopTime = System.currentTimeMillis();
    long elapsedTime = stopTime - startTime;
    System.out.println(elapsedTime);
  }
} 

Thông tin thêm tại hướng dẫn này


Như đã nói ở phần khác, currentTimeMillis () được gắn với ngày / giờ hệ thống và không được đảm bảo là đơn điệu (ví dụ: bạn có thể nhận được thời gian đã trôi qua âm).
oligofren

8

Mã không hoạt động vì biến đã trôi qua trong getElapsedTimeSecs()không phải là floathoặc double.


7

Không có tiện ích Đồng hồ bấm giờ được tích hợp sẵn nhưng kể từ JSR-310 (Java 8 Time), bạn có thể thực hiện việc này một cách đơn giản.

ZonedDateTime now = ZonedDateTime.now();
// Do stuff
long seconds = now.until(ZonedDateTime.now(), ChronoUnit.SECONDS);

Tôi chưa đánh giá điều này một cách chính xác nhưng tôi đoán việc sử dụng Đồng hồ bấm giờ của Guava sẽ hiệu quả hơn.



3

Đơn giản ra khỏi hộp Lớp đồng hồ bấm giờ:

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;
    }
}

Sử dụng:

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

3

sử dụng: com.google.common.base.Stopwatch, đơn giản và dễ dàng.

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>

thí dụ:

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

"Do something"

logger.debug("this task took " + stopwatch.stop().elapsedTime(TimeUnit.MILLISECONDS) + " mills");

nhiệm vụ này mất 112 nhà máy


2

thử cái này

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
Như đã nói ở phần khác, currentTimeMillis () được gắn với ngày / giờ hệ thống và không được đảm bảo là đơn điệu (ví dụ: bạn có thể nhận được thời gian đã trôi qua âm).
oligofren

2

Thử cái này:

/*
 * calculates elapsed time in the form hrs:mins:secs
 */
public class StopWatch
{ 
    private Date startTime;

    public void startTiming()
    {
        startTime = new Date();
    }

    public String stopTiming()
    {
        Date stopTime = new Date();
        long timediff = (stopTime.getTime() - startTime.getTime())/1000L;
        return(DateUtils.formatElapsedTime(timediff));
    }

}

Sử dụng:

StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();

2
DateUtils là một phần của Apache Commons, tại sao không chỉ sử dụng StopWatch của họ?
Bill Effin Murray

Trong hầu hết các trường hợp, bạn sẽ sử dụng một số thư viện phổ biến như đã đề cập trong các câu trả lời khác (ví dụ: Apache Commons). Bạn thậm chí có thể chỉ lấy các phần của thư viện nếu bạn không cần mọi thứ.
guyarad

2

Thử cái này.

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;
      }
} 

Sử dụng:

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

Bảng điều khiển:

StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.

Mặc dù đây có thể là hoặc không phải là những gì được yêu cầu trong câu hỏi, nhưng câu trả lời của bạn đã giúp tôi giải quyết vấn đề của mình. Cảm ơn bạn.
Toiletduck

currentTimeMillis()được gắn với ngày / giờ hệ thống và không được đảm bảo là đơn điệu (ví dụ: bạn có thể nhận được thời gian đã trôi qua âm).
oligofren

Nếu bạn quyết định xây dựng của riêng mình, chỉ cần sử dụng System.nanoTime()để luôn nhận được kết quả chính xác.
oligofren

2

Performetrics cung cấp một lớp học Đồng hồ bấm giờ tiện lợi, theo cách bạn cần. Nó có thể đo thời gian trên đồng hồ treo tường và hơn thế nữa: nó cũng đo thời gian CPU (thời gian của người dùng và thời gian của hệ thống) nếu bạn cần. Nó nhỏ, miễn phí và bạn có thể tải xuống từ Maven Central. Có thể tìm thấy thêm thông tin và ví dụ tại đây: 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  |
// +-----------------+----------------------+--------------+

Bạn có thể chuyển đổi các chỉ số thành bất kỳ đơn vị thời gian nào (nano giây, mili giây, giây, v.v.)

Tái bút: Tôi là tác giả của công cụ.



1

Thử cái này.

Giải pháp hoạt động hoàn toàn của đồng hồ bấm giờ Java

Ở đây bạn sẽ nhận được một giải pháp làm việc đầy đủ.

Chỉ là một đoạn mã từ giải pháp được liên kết ở trên:

Bạn có thể tạo một lớp như mã dưới đây và sử dụng phương thức bắt đầu và dừng của lớp này trước và sau phần mã, bạn muốn đo thời gian thực hiện.

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.";
  }

}

Cảm ơn bạn.


1
Mặc dù liên kết này có thể trả lời câu hỏi, nhưng tốt hơn hết bạn nên đưa các phần thiết yếu của câu trả lời vào đây và cung cấp liên kết để tham khảo. Các câu trả lời chỉ có liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi.
AS Mackay

Cảm ơn @ASMackay vì đề xuất của bạn. Tôi hoàn toàn đồng ý với bạn.
Sukriti Sarkar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.