Accurate Sleep for Java on Windows
To improve granularity of sleep you can try the following from this Thread.sleep page.
Bugs with Thread.sleep() under Windows
If timing is crucial to your
application, then an inelegant but
practical way to get round these bugs
is to leave a daemon thread running
throughout the duration of your
application that simply sleeps for a
large prime number of milliseconds
(Long.MAX_VALUE will do). This way,
the interrupt period will be set once
per invocation of your application,
minimising the effect on the system
clock, and setting the sleep
granularity to 1ms even where the
default interrupt period isn't 15ms.
The page also mentions that it causes a system-wide change to Windows which may cause the user's clock to run fast due to this bug.
EDIT
More information about this is available
here and an associated bug report from Sun.
Precise thread sleep needed. Max 1ms error
From the question tags I suppose you are on windows.
Take a look at Multimedia Timers, they advertise precision under 1ms.
Another options is to use Spin Locks but this will basically keep a cpu core at maximum usage.
Thread.sleep() optimization for small sleep intervals
That's easy to test:
public class Test {
static int i = 0;
static long[] measurements = new long[0x100];
static void report(long value) {
measurements[i++ & 0xff] = value;
if (i > 10_000) {
for (long m : measurements) {
System.out.println(m);
}
System.exit(0);
}
}
static void sleepyWait() throws Exception {
while (true) {
long before = System.nanoTime();
Thread.sleep(1);
long now = System.nanoTime();
report(now - before);
}
}
static void busyWait() {
while (true) {
long before = System.nanoTime();
long now;
do {
now = System.nanoTime();
} while (before + 1_000_000 >= now);
report(now - before);
}
}
public static void main(String[] args) throws Exception {
busyWait();
}
}
Run on my windows system, this shows that busyWait has microsecond accuracy, but fully uses one CPU core.
In contrast, sleepyWait causes no measurable CPU load, but only achieves millisecond accuracy (often taking as much as 2 ms to fire, rather than the 1 ms requested).
At least on windows, this is therefore a straightforward tradeoff between accuracy and CPU use.
It's also worth noting that there are often alternatives to running a CPU at full speed obsessively checking the time. In many cases, there is some other signal you could be waiting for, and offering an API that focuses on time-based resolution may steer the users of your API in a bad direction.
Accurate Sleep with cancellation
You shouldn't be implementing this at all.
In C++11 all basic necessary utilities for multithreading are implemented in the standard.
If you do not use C++11 - then switch to C++11 or higher - in the unfortunate case that you cannot, then use Boost which has the same features.
Basically, what you want to do with this functionality is covered by std::condition_variable
. You can put a thread into waiting mode by using function wait
(it accepts a condition function necessary for leaving the wait), wait_for
and wait_until
(same as wait
but with total waiting time limit) as well as notify_one
and notify_all
methods that wake the sleeping threads (one or all) and make them check the awakening condition and proceed with their tasks.
Check out std::conditional_variable
in the reference. Just google it and you'll find enough information about it with examples.
In case you do not trust std::conditional_variable
implementation for some reason, you can still utilize it for mini waits and awakening.
How Java precise sleep under 1ms
Game engines relies on Delta time for making games frame rate independent, Delata time is nothing but elapsed time between the last frame and current frame.
You can measure delta time as
DeltaTime = 1/FPS
So you can use this variable to make the game independent by multiplying this with your game variables, for example if you want to move a player independent of Frame rate you would do something like
Player.position = Player.position + MovementSpeed * DeltaTime
If initial position = 10
, MovementSpeed = 1
If FPS = 60
, DeltaTime = 0.016666667
then distance after 1 second is
Player.position = 10 + 1 * (0.016666667*60)
which is '11'
(Here it's multiplied with 60 to simply acomodate the fact that same calculation will run for 60 times when game is running at 60 FPS so Player.position will be updated by 0.016666666 for 60 Times)
If FPS = 30
, DeltaTime = 0.03333
then distance moved after 1 seconds isPlayer.position = 10 + 1*(0.03333*30)
which is '11'
So game can run independent of Frame Rates
You could try to calculate DeltaTime like:
//In main Game loop
current time = getSystemTime()
Delta time = current time - old time
old time = current time // save old time for next loop
Is sleep method accurate in timing precision?
Sleep is not the thing you want, as in here.
I suggest to read through this.
Thread.sleep and System.currentTimeMillis
Thread.sleep causes the currently executing thread to sleep
(temporarily cease execution) for the specified duration, subject to
the precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors, and resumption of execution
will depend on scheduling and the availability of processors on which
to execute the thread.
In any case, you cannot assume that invoking sleep will suspend the thread for precisely the time period specified.
Related Topics
Differencebetween Putting a Property on Application.Yml or Bootstrap.Yml in Spring Boot
Sharing a Persistence Unit Across Components in a .Ear File
How to Use Concurrentlinkedqueue
What's the Difference Between a Resource, Uri, Url, Path and File in Java
How to I Output Org.W3C.Dom.Element to String Format in Java
How to Check a Uploaded File Whether It Is an Image or Other File
Import Sun.Misc.Base64Encoder Results in Error Compiled in Eclipse
How to Achieve Conditional Resource Import in a Spring Xml Context
Why Did Servlet.Service() for Servlet Jsp Throw This Exception
How to Make Hashmap Work with Arrays as Key
Compile Error: Package Javax.Servlet Does Not Exist