2017-09-19 62 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 
    } 


}