How do I get accurate timestamps for job execution durations in a multithreaded application?
How to add timestamp into a multi threaded program where I have:
- J3 dependent on J1 & J2
- J5 dependent on J4
And get the different times of executions of each job (thread).
I have 6 different files of J1, J2, J3 (where I have joined J1 & J2), J4, J5 (where I have joined J4) an开发者_运维百科d J6 (where I start all the threads).I have added this function:
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:ms");
Calendar cal = Calendar.getInstance();
Sample Code(of one thread) --
import java.io.*;
import java.*;
import java.util.*;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Job1 extends Thread{
String msg;
public void run()
{
System.out.println("Execution of job1 (addition job) started");
System.out.println();
System.out.print("3+2=" +(3+2));
System.out.println();
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:ms");
Calendar cal = Calendar.getInstance();
}
Job1(String mg)
{
msg=mg;
}
}
But, I am getting the same time for every thread.
Update
This is the output I am getting.
C:\Program Files\Java\jdk1.6.0_03\bin>javac threadcontainer.java
C:\Program Files\Java\jdk1.6.0_03\bin>java threadcontainer
J1->4719906194666
J2->4719906696464
Execution of job1 (addition job) started
3+2=5
J4->4719911159535
Execution of job4 (multiplication job) started
3*2=6Job 5 executing
J5-> 4719911737462
Execution of job2 (subtraction job) started
3-2=1Job 3 executing
J3->4719912405874
You should use System.nanoTime() is much more accurate and much faster.
Calendar is one of the most expensive objects you can create and using a date format is likely to be very inefficient. The ":ms" doesn't do anything useful, so I suspect you only have second resolution. If you want milli-seconds use ".SSS" as per the javadoc.
First, post more code, so that we can see what you are really doing and what you to with the date format and so on.
And then: Javadoc for SimpleDateFormat says:
Synchronization
SimpleDateFormat is not thread-safe. Users should create a separate instance for each thread.
Which may cause what you see.
Use java.lang.System.nanoTime() to measure elapsed time - it's the most accurate timer available to you. It's an arbitrary counter though (it doesn't represent a time as such, it just counts nanoseconds), so you'll need to use it like this:
long t1 = System.nanoTime();
// do something
long t2 = System.nanoTime();
long elapsedTime = t2 - t1; // in nano-seconds, so remember to scale!
There's a good thread here that goes into deep technical detail on the nanoTime call.
tl;dr
Instant.now() // Current moment in UTC
.toString() // Generate string in standard ISO 8601 format.
2018-01-23T04:52:47.830065Z
For elapsed time:
Duration.between( instantThen , Instant.now() )
java.time
The modern approach uses java.time classes rather than the troublesome old legacy date-time classes such as Calendar
.
The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now() ; // Capture current moment in UTC.
While an Instant
can represent a value in nanoseconds, it has limitations is capturing the current moment.
- In Java 8, the current moment is captured only up to milliseconds.
- In Java 9, a new
Clock
implementation now captures the current moment with a finer granularity.
In Java 9.0.1 on macOS Sierra, I am seeing current moments captured with microseconds.
2018-01-23T04:52:47.830065Z
To generate a String in standard ISO 8601 format seen above, simply call toString()
.
String output = Instant.now().toString() ;
I suggest using the Instant
in UTC with standard formatting for your logging needs. But if you insist otherwise, see the DateTimeFormatter
& ZonedDateTime
classes.
If you are calculating elapsed time, use Duration
class.
Duration d = Duration.between( instantThen , Instant.now() ) ;
To report, call Duration::toString
to generate a String in standard ISO 8601 format.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.
精彩评论