Lock A Runnable Until Finished
Solution 1:
The looper
object is solely owned by the timer.schedule
so no-one can call that object's run
method except the timer.schedule
. If the run
method takes longer that the period you have specified then it is likely that the run method will be called again before it completes - especially since you have passed off the actual running of the the task to the UI thread.
You have two simple alternatives:
- Set a flag in your
run
method indicating that you are running and makerun
do nothing if it is set. - Fire off the timer after a fixed delay only, not with a repeat time. At the end of your run, fire it off again.
For 1:
classLooperextendsTimerTask {
// ** Add this **volatilebooleanrunning=false;
publicLooper() {
}
@Overridepublicvoidrun() {
// ** Add this **if (!running) {
running = true;
try {
runOnUiThread(newRunnable() {
@Overridepublicvoidrun() {
}
});
// ** Add this **
} finally {
running = false;
}
}
}
}
Second method:
timer.schedule(newlooper(m_mainView, this, Rate),newDate());
...
classLooperextendsTimerTask {
finallong rate;
final Looper looper;
publicLooper(long rate) {
this.rate = rate;
looper = this;
// ...
}
@Overridepublicvoidrun() {
runOnUiThread(newRunnable() {
@Overridepublicvoidrun() {
// ...newTimer().schedule(looper, newDate(newDate().getTime() + rate));
}
});
}
}
Solution 2:
You should add synchronized
to the method declaration like this:
publicsynchronizedvoidrun()
Solution 3:
First of all, why is there any risk that the run method will be called again? If that's true it sounds like a design deficiency to me. Second, instead of TimerTask, you might be better off using a ScheduledExecutorService instead. That's the standard, simplest and safest way of executing scheduled tasks at a fixed interval. Your user code won't be accessible from anything but the executor service and you can get a ScheduledFuture from it to get a return value so that you know when the task is done (the ScheduledFuture blocks when you call get()). Take a look at Java Concurrency in Practice for more...
Post a Comment for "Lock A Runnable Until Finished"