• Post Reply Bookmark Topic Watch Topic
  • New Topic

How can I have a sleep method that make a Thread sleeps for EXACTLY the time I set?  RSS feed

 
Enrico Tamellin
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello!

This is the description of the method sleep(long millis) of JVM 1.5.0. here the link


Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds. The thread does not lose ownership of any monitors.


But I realized that it doesn't cause an interruption of the Thread of exactly the time you set.
so here the Question: IS THERE A WAY TO CREATE A SLEEP METHOD OF EXACTLY THE TIME WE WANT IN JAVA?


..a solution could be the following code



The code can find the sleeps that are less than 40 milliseconds and give to them an other sleep of the time you need to reach 40 milliseconds.

But it has 2 probelms:
- it can't control the sleeps that are more than 40 milliseconds
- In the block of code between A and B the Thread is working and it is not totally sleeping. I would like to have a way to have a Thread that exactly do nothing for whole 40milliseconds

Any suggestions for that?
 
Henry Wong
author
Sheriff
Posts: 23284
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
it can't control the sleeps that are more than 40 milliseconds


Well, there is nothing that you can do about this. Whether you get a timeslice, after the sleep has completed, is dependent on the Operating System. If the OS is really busy, it may take some time before the thread can wake up.


In the block of code between A and B the Thread is working and it is not totally sleeping. I would like to have a way to have a Thread that exactly do nothing for whole 40milliseconds


Actually, your example doesn't really work. The sleep() method doesn't return early without an exception condtion. If the sleep() method returns early, it will be via a interrupted exception. This means that it will be transitioned to the catch block. Having the loop in the try block doesn't do anything -- you need to move the whole try-catch blocks into the while loop.

Henry
 
Enrico Tamellin
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello Henry,
Thank you for the answer


Henry Wong wrote:If the sleep() method returns early, it will be via a interrupted exception. This means that it will be transitioned to the catch block.
Henry


I didn't understand so much this point. I write a code that can detect when a sleep method wakes up early, because I realized something weird with the following code.

Think about this simple class



it just measures the exact time of the sleep. In case the thread wakes up early it prints "Exception". But I had this weird result



it's really strange because there are a lot of measurements that are less than 10 milliseconds!! And no Exception was cast!

It works weird also with others values of sleep time (in the code line //A): for example 20, 50, 100, 1000!
For example this is the output with sleep(1000)



So if it is sure that the sleep method returns early only with an Exception I can guess the measuraments give by System.nanoTime() is not precise! It gives me problems also using System.currentTimeMillis()!

- What I wrong? Probably I miss some important point!
- Is the sleep method not precise or it is the System.nanoTime()?
- And how can I set up a method that wait for at least n milliseconds I set?
- Do you have any suggestions to improve the measurements?

... I start to get confused!
 
Henry Wong
author
Sheriff
Posts: 23284
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


First of all, currentTimeMillis() is only good to a milli -- so being off by 1/5 of a milli is actually pretty good !! Second of all, nanoTime() is only as good as the OS that it is on top off. The JavaDoc clearly states that you can't use it to get nano accuracy. If you want to get nano accuracy, you will need to run it on a platform with an OS, and hardware, that can deliver that accuracy.

Having said that... just what JVM / OS combo are you using? On my computer, all but a few returned after 10 millis, and the few that didn't, they were all less than 1/10 of a milli early -- which I attibuted to the accuracy of my computer.

Henry
 
Henry Wong
author
Sheriff
Posts: 23284
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

And BTW, when the JavaDoc refers to the sleep() method returning early, it is referring to interruptions -- meaning really early. Like you ask for 10 seconds, and it returns after 5 seconds. It is not talking about returning early based on the accurcy of the system clock.

Henry
 
Enrico Tamellin
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So it's definitely a problem of precision of OS! This make everything more complicated!

I run it in Windows XP SP2 Home Edition. Probably Windows is not good for this job!

Is there a way to know before the resolution of a SO? It will be quite stressful try all the distributions to find the correct one! :?

I am gonna try with Fedora! If I have good results I am going to post it! :-)
 
Enrico Tamellin
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Henry Wong wrote:
And BTW, when the JavaDoc refers to the sleep() method returning early, it is referring to interruptions -- meaning really early. Like you ask for 10 seconds, and it returns after 5 seconds. It is not talking about returning early based on the accurcy of the system clock.

Henry


Ah ok! Thanks!
First of all I thought about interruptions because in my java program I have to run a lot of different Threads, and I don't have the control of most of them! (The final project has to run under Tomcat). So I thought there were some interruptions by other Threads
 
shiva sarna
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,


If you want to guarantee that Thread should wake exactly after the time then the best this is to use the wait() method.

For further explaination check this article LINK.

Protozoa
 
Enrico Tamellin
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
shiva sarna wrote:Hi,


If you want to guarantee that Thread should wake exactly after the time then the best this is to use the wait() method.

For further explaination check this article LINK.

Protozoa


Thanks Shiva! very interesting article!


I have a little news:
I ran the program under Ubuntu both 32 bit and 64 bit version and all the values calculated are higher than the sleep time set.
So apparently, the sleep method doesn't wake earlier and the System.nanoTime() is more precise. For sure, as Henry Wong suggested, the precision depends on the OS used!

Now I am trying some techniques to improve the other problem: when the Thread is executed too after the time I set.
It's quite difficult to have improvements because in this case it will work well if the scheduler choose to execute the Thread exactly after it wakes up.
The more threads are running in the system, the higher is this problem!
Of course you can't modify the OS scheduler rules, but you can use the priorities.
Here there is a very naive solution, but it improve a bit the solution to this problem.



This solution is not the best one, but I realized that it improves a bit if I start this code in a loop in many Threads in the same time.
This problem is a bit linked also to the work of the Garbage Collector (it's a thread you can't control and it can work exactly when out Thread wakes up) ... but it's better if I'll open an other post.

If I'll find a better solution, I'll post it.

Cheers,
Enrico

 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!