2017-01-10 9 views
1

メールクライアントからメールサーバーから新しいメールをダウンロードするのと同様の問題を解決しようとしています。私は定期的に実行されるタスクを持っています(次の繰り返しは最後のタスクが終了してから10分後です)が、手動でタスクを実行する可能性もあります。Javaで手動起動が可能な通常のジョブを処理する

ジョブを手動で実行しようとしていて、ジョブがこの瞬間に実行されていない(後で任命される)と、私はアポイントを取り消して今スケジュールしています。ジョブがすでに実行されている場合、私はキャンセルしませんが、完了するまで待ってからもう一度実行します。しかし、1つのタスクだけがこの方法で待つことができます。

私の問題は、ジョブを同期させてスレッドを安全にし、同時にジョブを2回実行しないようにする方法がわからないことです。

もっと明確にする。主な問題は、ジョブが実行されているかどうかを簡単に確認し、質問とアクションの間で状況が変わる可能性があるため、取得した内容に基づいて判断するだけでは不十分であることです。これは短いスパンですが、確率はゼロではありません。そして、同じ問題は、彼の走りの終わりに仕事を再開すべきかどうかを決めることです。私の決定が変数や他のif節の値に基づいている場合、その値をテストして何らかのアクションを実行する間に、他のスレッドがそれを変更することができ、2つのスケジュールされたジョブで終了するか、まったく終了しない可能性があります。

答えて

0

DelayQueueを使用したことがありますか?

ジョブをnowに実行させるには、0フォームgetDelay(TimeUnit unit)を返すように説得する必要があります。だから、唯一の試みは、スレッドを実行するために

public class OneQueuedThread extends Thread { 
    static int numberRunning =0; 
    public void run() { 
     if (numberRunning<2) { 
      synchronized (OneQueuedThread.class){ 
       if (numberRunning<2) { 
        numberRunning++; 
        // ---------------your process runs here 
        numberRunning--; 
       } 
      } 
     } 
    } 
} 

+0

私はどのようにこの助けることができる理解していません。キューの先頭を取得するように依頼することもできますが、getDelayが1ミリ秒を返すため、nullを取得できる場合があります。これを基にして決定を下すと、実行されていないと予想されますそれはそれが2回実行される原因になります。 –

+0

独自の[遅延](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Delayed.html)を作成し、キューに入れます。その後、外部で '0'を返すように操作することができます。 – OldCurmudgeon

0

それはあなたがについて言っているチェックを行うための主な方法は、同じチェックを繰り返すその後をロックとし、確認することですそれが既に実行されている間は、実行中のスレッドの終了まで待機し、その後に開始します。スケジュールについては

は、のはTimerTaskを機能を使ってみましょう:

 public class ScheduledTask extends TimerTask { 
     ScheduledTask instance; 


     /** 
     * this constructor is to be used for manual launching 
     */ 
     public void ScheduledTask(){ 
      if (instance == null){ 
       instance = this; 
      } else { 
       instance.cancel(); 
      } 
      instance.run(); 
     } 

     /** 
     * This constructor is to be used for scheduled launching 
     * @param deltaTime 
     */ 
     public ScheduledTask(long deltaTime){ 
      instance = this; 
      Timer timer = new Timer(); 
      timer.schedule(instance, deltaTime); 

     } 

     public void run() { 
      OneQueuedThread currentTread; 
      currentTread = new OneQueuedThread(); 
      currentTread.start(); 
     } 
    } 
関連する問題