简体   繁体   中英

Java - alternative to thread.sleep

I have a requirement to pause a while loop for a specific number of milliseconds. I have tried using Thread.sleep(duration) but it is not accurate, especially in a looping scenario. Millisecond accuracy is important in my program.

Here is the algorithm where I don't want to go back to check for condition until expectedElapsedTime has passed by.

while (condition) {
    time = System.currentTimeMillis();
    //do something
    if (elapsedTime(time) < expectedElapsedTime) ) {
        pause the loop  // NEED SUBSTITUTE FOR Thread.sleep()
    }
    // Alternative that I have tried but not giving good results is 
    while ((elapsedTime(time) < expectedElapsedTime)) {
        //do nothing
    }
}

long elapsedTime(long time) {
   long diff = System.currentTimeMillis() - time;
   return diff;
}

Try a ScheduledThreadPoolExecutor . It's supposed to give more reliable timing results.

What do you expect?

If you go to sleep then once your process is again runable it will have to wait for the thread scheduler to schedule it again.

I mean if you go to sleep for 50 seconds that does not mean that your process will be running in exactly 50 seconds.Because ater it wakes and is runnable it will have to wait to be scheduled to CPU which takes extra time plus the time you have for context switch.

There is nothing you can do to control it so you can not have the accuracy you are saying.

For your case I would suggest a spinning loop instead.

long now = System.currentTimeMillis();   
while(now < expectedElapsedTime){
    now = System.currentTimeMillis();
}

Java is not a real-time system, you can not make a thread go away and come back on such a tight schedule. To schedule your program execution down to millisecond you need to use a different platform - like simpleRTJ or Java Real-Time extension .

The delay is likely to arbitrarily chosen, so I would question your need to real time interval timing.

If you need read time you need to busy wait for the time to reached. Giving up the CPU means you can't guarantee you will get it back exactly when you want.

如果你想要使用声音准确,你可以使用音序器并在BPM中设置速度:sequencer.setTempoInBPM(120);

The solution is to use a handler with a runnable and use of the method 'postDelayed'. Example:

new Handler().postDelayed(new Runnable() {
public void run () {
    // Do delayed stuff!
}
}, 5000L); //5 seconds delay 

https://stackoverflow.com/a/21680858

You could implement wait/notify mechanism and delegate to another thread the responsibility of notify the other thread in wait state that the amount of time is passed and that it can go ahead ...

For example when the threadA need to wait for a certain amount of time you can put the thread in wait state and start a timer task that after a certain amount of time (interval ) call notify and wake up the ThreadA that go ahead, this could be an alternative .

Don't forget about garbage collector pauses. It can beat all your plans

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM