Timer: period less than a millisecond - java

As the title, is there a way to get the Timer working under the threshold of a millisecond?
My question is similar the following one, but it is intended for Java:
Thread.Sleep for less than 1 millisecond

If you want to sleep, Thread.sleep has 2 methods, one of which accepts nanoseconds. If you want to schedule a task, you can use a ScheduledExecutorService which schedule methods can use nanoseconds too.
As explained by #MarkoTopolnik, the result will most likely not be precise to the nanosecond.

Thread.sleep(long millis, int nanos)
Also check out this answer with details on issues with this on Windows.

You could wait on an object that nobody will notify...
synchronized (someObjectNobodyWillNotify) {
try {
someObjectNobodyWillNotify.wait(0, nanosToSleep);
}
catch (InterruptedException e) {
Thread.interrupt();
}
}
(In this scenario, I'm guessing spurious wakeups are okay. If not, you need to record your System.nanoTime() at the start and wrap the wait in a loop that checks that enough time has elapsed.)

The java.util.concurrent package uses TimeUnit for timing. TimeUnit has a NANOSECONDS field.

Related

Java real fixed time interval

I'm doing some tasks using Java. I have some problems with timing: I need to set up a timer with a fixed period of repetition. I tried both, the standard Timer, and TimerTask and the ScheduledExecutor, but both work in an approximate manner, i.e. if I set an interval of 40 milliseconds, using the following code (for Executors)
m_executor = Executors.newScheduledThreadPool(5);
Runnable thread = new TheThread();
m_executor.scheduleWithFixedDelay(thread, 0, 40000000, TimeUnit.NANOSECONDS);
And then I try to print "time" of each execution
private static final class TheThread implements Runnable {
#Override
public void run() {
System.out.println(System.nanoTime()/1000000);
}
}
The result is something like this:
xxxxxx300
xxxxxx345
xxxxxx386
xxxxxx428
...
As you can see, if I correctly understand nanoTime() the function is called at a random intervals, close to that I specified (40 milliseconds), but not exactly what I specified!
When I worked with C and Win32s, for example, I was able to use the CreateTimerQueueTimer() function that is highly accurate, and the callback function was called every 40 milliseconds:
xxxxxx300
xxxxxx340
xxxxxx380
...
I tried to move time measurement to avoid the printing time. I also tried to use scheduleAtFixedRate(), but unfortunately the period varies between 35 and 47 ms (set to 40 in the method).
I'm wondering how people can make software such emulators or similar things, that requires a precise period observance...:-)
I thought of a possible solution that I would like to show you and ask to you, experts:) how this idea could be applicable (and safe)
The problem here is to run some methods every X milliseconds, say 40 ms. The question here is about Java timer/timing, but what about this simple solution?
public class MyEmulator extends Thread {
private long start = 0;
private long end = 0;
#Override
public void run() {
long exec_time;
start = System.nanoTime();
/*
* Do the emulator-loop
*/
end = System.nanoTime();
exe_time = (end - start)/1000000;
// wait with a whil() (40 - exec_time)
}
}
With this solution, when I print the elapsed time after the waiting whilt() is ended the result is exactly 40 ms (without decimal, that is not quit important).
Do you think it would be safe, i.e. are really 40 ms?
I don't think you're going to be able to manage this in Java with this level of precision. Unlike your C/Win32 solutions, your Java solution is running in a JVM with multiple threads (of varying priority) and with garbage collection running and taking resources.
Having said that, I would experiment with the scheduleAtFixedRate() method, which executes at a regular period. scheduleWithFixedDelay() will execute and upon completion delay for a fixed amount of time. Hence not accounting for the time taken for your method to actually run.

Update current time date without exploding in memory

I have written the following Java code:
Calendar now = Calendar.getInstance();
now.setTime(new Date());
Date currentDate = null;
while (now.compareTo(stop) < 0 ) {
currentDate = new Date();
now.setTime(currentDate);
}
that is meant to track down the time passing while other components (in particular: a Twitter Streaming listener) perform other actions. So, this is not meant to be a simple sleep, since other components are running in the meanwhile: this loop is just meant to keep the machine occupied for a while, until the date indicated by stop arrives.
However, by doing this the memory size keeps increasing a lot. I profiled the thing and I saw that this generates a huge amount of Date objects in memory.
Is there a smarter way of doing this?
Thank you in advance.
The minimum change is to use setTimeInMillis using System.currentTimeMillis rather than setTime:
while (now.compareTo(stop) < 0 ) { // Ugh, busy wait, see below
now.setTimeInMillis(System.currentTimeMillis());
}
...or actually, just use milliseconds in the first place:
long stopAt = stop.getTimeMillis();
while (System.currentTimeMillis() < stopAt) { // Ugh, busy wait, see below
}
However, surely with broader context there's a way to avoid busy-waiting at all. Busy-waits are almost never appropriate.
So, this is not meant to be a simple sleep, since other components are running in the meanwhile: this loop is just meant to keep the machine occupied for a while, until the date indicated by stop arrives.
Presumably those components are running on other threads, as your while loop is a busy-wait.
That being the case, this thread should sleep — either for a period of time, or until it's woken up by something else.
For instance, you haven't said what stop is, but as you're using it with compareTo presumably it's a Calendar. So it should be possible to get the difference (in milliseconds, via getTimeInMillis) between stop and now, and sleep rather than busy-waiting:
Calendar now = Calendar.getInstance(); // Initializes to "now", no need to do that yourself
long delay = stop.getTimeInMillis() - now.getTimeInMillis();
if (delay > 0) {
Thread.sleep(delay);
}

Determining amount of time (in fractions (however small)) of a second in java (on finding solution)?

I have a program that will throw a simple exception when it's completed, when that exception is thrown is there any way to treat it like a stop-watch and stop the timer and display how long it took to solve the problem given?
Thanks a lot!
Milliseconds
System.currentTimeMillis() is a function that returns the current time in milliseconds. You can get invoke this function once when you start, and again when finished, then find the difference to determine the amount of time elapsed.
For example:
public void foo() {
long startTime = System.currentTimeMillis();
try {
doStuff();
} catch (Exception e) {
long endTime = System.currentTimeMillis();
long elapsedTime = endTime - startTime;
System.out.println("This operation took " + elapsedTime + " milliseconds.");
}
}
Nanoseconds
You can also use System.nanoTime() which is precise to nanosecond (rather than to the millisecond), but it is more limited in how much of a difference it can portray.
In the simplest case, use System.currentTimeMillis() to record the start and stop times (subtracting start from stop in the catch block). There are more complicated approaches with pretty interfaces. See, for example:
Stopwatch class for Java
Just be sure that the timer is in scope whenever the exception is caught.
Exception handling is an especially poor method of flow control - much better to break out of a loop, set the loop conditional to false, or return out of your recursive method.
For your actual question, you can get the system time with System.currentTimeMillis() at the start of your program, and then again at the end, and compare. Note that the system call is only accurate to 15ms, so this is only really useful for long running programs.

Will this pause my Java thread for a minute?

Am I doing something really stupid here? I am trying to execute a method every minute or so, forever, or until I stop the program.
while(true) {
this.doSomethingPeriodically();
Calendar now = Calendar.getInstance();
int minutes = now.get(Calendar.MINUTE);
int resume = minutes + 1;
while (now.get(Calendar.MINUTE) < resume) {
// waiting for a minute
}
}
This code will never leave the loop. It's an endless loop, since the Calendar instance refered to by now won't change.
Also, what you try to do here is implement busy waiting which is a very bad idea (it uses CPU time doing nothing interesting).
The correct way to sleep is to use Thread.sleep().
the simplest way for execute tasks repeteadly in java is the java.util.TimerTask and java.util.Timer api.
A simple code is:
public class PrinterTimerTask extends java.util.TimerTask {
#Override
public void run() {
System.out.println( 'Current time is: ' + System.nanoTime() );
}
public static void main(String[] args) {
long delay = 0;
long period = 60000;
java.util.Timer timer = new java.util.Timer(threadName);
PrinterTimerTask task = new PrinterTimerTask();
timer = new Timer("SomeThreadNameForProfiler");
timer.schedule( task, delay, period );
}
}
Variables:
task - task to be scheduled.
delay - delay in milliseconds before task is to be executed.
period - time in milliseconds between successive task executions.
More info:
Timer and TimerTask javadoc:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/Timer.html
http://java.sun.com/j2se/1.5.0/docs/api/java/util/TimerTask.html
Another example:
http://www.javapractices.com/topic/TopicAction.do?Id=54
[]'s,
And Past
Try using the Timer class instead. It's meant for this sort of thing:
http://www.javapractices.com/topic/TopicAction.do?Id=54
https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Timer.html
Edit:
I just read that there's a newer replacement for Timer: ExecutorService. I've never used it, but it seems to have some advantages:
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ExecutorService.html
Java Timer vs ExecutorService?
Try using sleep instead, as it won't cause the processor to continue working on the thread:
Thread.sleep()
while(true) {
this.doSomethingPeriodically();
Thread.sleep(60000);
}
It would be better to use a Timer or at least use a sleep.
What you're trying to do here is called busy waiting. You are unnecessarily using huge amounts of CPU time (and you would even be using unnecessary memory if you fixed your bug and created a new Calendar instance in each loop).
What you actually want is the method Thread.sleep(), it is pretty well explained in a tutorial on sun.com.
It's better to use the sleep function: CurrentThread.sleep() and you specify the number of milliseconds that you want as a delay. It's better than busy waiting...

System.nanotime running slow?

One of my friends showed me something he had done, and I was at a serious loss to explain how this could have happened: he was using a System.nanotime to time something, and it gave the user an update every second to tell how much time had elapsed (it Thread.sleep(1000) for that part), and it took seemingly forever (something that was waiting for 10 seconds took roughly 3 minutes to finish). We tried using millitime in order to see how much time had elapsed: it printed how much nanotime had elapsed every second, and we saw that for every second, the nanotime was moving by roughly 40-50 milliseconds every second.
I checked for bugs relating to System.nanotime and Java, but it seemed the only things I could find involved the nanotime suddenly greatly increasing and then stopping. I also browsed this blog entry based on something I read in a different question, but that didn't have anything that may cause it.
Obviously this could be worked around for this situation by just using the millitime instead; there are lots of workarounds to this, but what I'm curious about is if there's anything other than a hardware issue with the system clock or at least whatever the most accurate clock the CPU has (since that's what System.nanotime seems to use) that could cause it to run consistently slow like this?
long initialNano = System.nanoTime();
long initialMili = System.currentTimeMillis();
//Obviously the code isn't actually doing a while(true),
//but it illustrates the point
while(true) {
Thread.sleep(1000);
long currentNano = System.nanoTime();
long currentMili = System.currentTimeMillis();
double secondsNano = ((double) (currentNano - initialNano))/1000000000D;
double secondsMili = ((double) (currentMili - initialMili))/1000D;
System.out.println(secondsNano);
System.out.println(secondsMili);
}
secondsNano will print something along the lines of 0.04, whereas secondsMili will print something very close to 1.
It looks like a bug along this line has been reported at Sun's bug database, but they closed it as a duplicate, but their link doesn't go to an existing bug. It seems to be very system-specific, so I'm getting more and more sure this is a hardware issue.
... he was using a System.nanotime to cause the program to wait before doing something, and ...
Can you show us some code that demonstrates exactly what he was doing? Was it some strange kind of busy loop, like this:
long t = System.nanoTime() + 1000000000L;
while (System.nanoTime() < t) { /* do nothing */ }
If yes, then that's not the right way to make your program pause for a while. Use Thread.sleep(...) instead to make the program wait for a specified number of milliseconds.
You do realise that the loop you are using doesn't take exactly 1 second to run? Firstly Thread.sleep() isn't guaranteed to be accurate, and the rest of the code in the loop does take some time to execute (Both nanoTime() and currentTimeMillis() actually can be quite slow depending on the underlying implementation). Secondly, System.currentTimeMillis() is not guaranteed to be accurate either (it only updates every 50ms on some operating system and hardware combinations). You also mention it being inaccurate to 40-50ms above and then go on to say 0.004s which is actually only 4ms.
I would recommend you change your System.out.println() to be:
System.out.println(secondsNano - secondsMili);
This way, you'll be able to see how much the two clocks differ on a second-by-second basis. I left it running for about 12 hours on my laptop and it was out by 1.46 seconds (fast, not slow). This shows that there is some drift in the two clocks.
I would think that the currentTimeMillis() method provides a more accurate time over a large period of time, yet nanoTime() has a greater resolution and is good for timing code or providing sub-millisecond timing over short time periods.
I've experienced the same problem. Except in my case, it is more pronounced.
With this simple program:
public class test {
public static void main(String[] args) {
while (true) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
OStream.out("\t" + System.currentTimeMillis() + "\t" + nanoTimeMillis());
}
}
static long nanoTimeMillis() {
return Math.round(System.nanoTime() / 1000000.0);
}
}
I get the following results:
13:05:16:380 main: 1288199116375 61530042
13:05:16:764 main: 1288199117375 61530438
13:05:17:134 main: 1288199118375 61530808
13:05:17:510 main: 1288199119375 61531183
13:05:17:886 main: 1288199120375 61531559
The nanoTime is showing only ~400ms elapsed for each second.

Categories

Resources