2017-09-19 35 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()は時間がかかる何かをします。私doMoreStuffを続行する前にdoStuffが実行されていれば終了するまで待つ必要があります。

ここで使用できるwaitUntilFinishedメソッドを追加する(法的)方法はありますか、java.util.Timerクラスを自分自身にコピーしてメソッドを実装するだけですか?

答えて

0

TimerTaskは非同期であると考えられます。

スレッド管理を正しく実装する必要があります。 Executorsまたはスレッドプールを使用して、タスクの実行ライフサイクルを監視します。

+0

別のスレッドを使用するのは簡単ですか? – Wietlol

+0

非同期かどうかによって異なります。 doStore()は完了していますか? – oldmanswit

+0

doMoreStuff()は、doStuff()が使用するいくつかのCloseableを閉じます。単純な言い方をすれば、それはdoStuff()に依存し、もう一度実行しないでください。 – Wietlol

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 
    } 


} 
関連する問題