考虑以下示例:
// Helper constructor
public Timer(final TimerTask action, final long interval)
{
scheduleAtFixedRate(action, 0, interval);
}
... (different class)
private Timer myTimer;
public void start()
{
myTimer = new Timer(new TimerTask(){
@Override
public void run()
{
doStuff(); <<----------------------------
} |
}, 10); |
} |
|
public void stop() |
{ |
myTimer.cancel(); |
myTimer.purge(); |
doMoreStuff(); // << may not be called while doStuff is running!
}
doStuff()做了一些需要时间的事情。我必须等到doStuff已经完成,如果有任何正在运行之后我想继续使用doMoreStuff。
是否有任何(合法的)方法可以添加我可以在这里使用的waitUntilFinished方法,或者我应该将java.util.Timer类复制到我自己的方法并自己实现该方法? / p>
答案 0 :(得分:0)
TimerTask应该是异步的。
您需要正确实现线程管理。 使用Executors或线程池来监视任务执行生命周期。
答案 1 :(得分:0)
您可以使用显式锁定来执行此操作。
任务需要为doStuff()
获取锁定,并在无法获得锁定后退出,事实上,它永远不会再次尝试doSuff()
。
stop()
方法将取消Timer
并锁定。它将阻塞直到它获得锁定,因此如果doStuff()
正在进行,它将不得不等待。一旦它具有锁定,它就会明确地禁用该任务,这样在释放锁定之后,剩余的任务运行将不再尝试doStuff()。
public class TimerStuff {
private Timer myTimer;
private Lock lock;
private ScheduledTask scheduledTask;
public void start() {
lock = new ReentrantLock();
myTimer = new Timer();
scheduledTask = new ScheduledTask(lock);
myTimer.schedule(scheduledTask, 0, interval);
}
public void stop() {
myTimer.cancel(); // stop the scheduling
lock.lock(); // if doStuff is busy, we'll block until it's finished, once we have the lock the task cannot doStuff()
try {
scheduledTask.disable(); // once we release the lock, the task won't attempt to run again
doMoreStuff(); // we're certain doStuff() isn't running, and won't run after this
} finally {
lock.unlock();
}
}
private void doMoreStuff() {
//***
}
}
class ScheduledTask extends TimerTask {
private final Lock lock;
private volatile boolean mayRun = true;
public ScheduledTask(Lock lock) {
this.lock = lock;
}
@Override
public void run() {
mayRun = mayRun && lock.tryLock();
if (mayRun) {
try {
doStuff();
} finally {
lock.unlock();
}
}
}
public void disable() {
this.mayRun = false;
}
private void doStuff() {
// ... the stuff
}
}