2017-09-19 61 views
0

请看下面的例子:的Java的TimerTask等待最后一个任务

// 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方法的任何(合法)方法,我可以在这里使用,或者我应该只是复制'n'paste java.util.Timer类到我自己并自己实现该方法?

回答

0

TimerTask应该是异步的。

您需要正确实施线程管理。 使用执行程序或线程池来监视任务执行生命周期。

+0

是不是更容易只使用不同的线程? – Wietlol

+0

取决于它们是否是异步的。 doMoreStuff(),取决于doStuff()是否完整? – oldmanswit

+0

doMoreStuff()关闭doStuff()使用的一些Closeables ...所以简单地说,是的,它取决于doStuff()不再运行,并且再也不会运行 – Wietlol

0

你可以用明确的锁来做到这一点。

该任务需要获取锁定才能doStuff(),并且一旦无法获得锁定就会退后,实际上,它永远不会再尝试到doSuff()

stop()方法将取消Timer并锁定。它会阻塞,直到锁定,所以如果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 
    } 


}