I have a separate thread running in my main class. It needs to send a message every 100 milliseconds, but EXACTLY every 100ms. I am wondering if it is accurate enough to be used as such, or if there is an alternative to have something happen exactly 10 times a second.
class ClockRun implements Runnable {
@Override
public void run() {
double hourlyRate = Double.parseDouble(prefs.getString("hourlyRate", ""));
double elapsedTime = 0;
do {
while(clockRun){
double amount = hourlyRate / 360 /100 * elapsedTime;
elapsedTime++;
Bundle clockData = new Bundle();
clockData.putString("value", String.format("$%.2f", amount));
Message message = Message.obtain();
message.setData(clockData);
handler.sendMessage(message);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}while (mainRun);
Notify.viaToast(getApplication(), "Thread stopped.");
}
}
No it is not accurate at all,
From the docs:
(temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. In other words, this sleep is OS or environment dependant, you can't predict the OS scheduling decision, plus, the sleep can be terminated by an interrupt.
Again from the docs:
In any case, you cannot assume that invoking sleep will suspend the thread for precisely the time period specified
Moreover, it is not efficient because you will be wasting CPU cycles just for sleeping.
ScheduledExecutorService will provide a better precision and performance.
Simply wrap your task in Callable or Runnable and use ScheduledExecutorService
to execute them, there are plenty of tutorials out there.
I recommend using ScheduledThreadPoolExecutor's scheduleAtFixedRate()
method, because it fires every given time, no matter how long it takes for the code in run()
method to complete.
I think it would be something like this:
Runnable runnable = new Runnable() {
@Override
public void run() {
// Do your stuff
}
});
ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
ses.scheduleAtFixedRate(runnable, 0, 100, TimeUnit.MILLISECONDS);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With