2017-12-13 19 views
1

私には次のようなものがあります:時間制限機能

機能requestValue:この機能を何回か呼び出す必要があります。私が呼び出すたびに、それはいくつかの値を計算する必要がありますX次に計算された値をパラメータとして別の関数submitValue(X)を呼び出します。ただし、5秒以内に計算が終了しない場合は、submitValue(-1)を呼び出す必要があります。

これは、問題をできるだけ単純にするために必要なものの一例に過ぎず、関数は何も計算しません(スリープは時間制限を超えてシミュレートするために使用されます)。

私がやったことはThreadクラスを拡張し、停止したとしてスレッドをマークする機能を追加されます。ここでは

class myThread extends Thread{ 
    boolean stop = false; 
    @Override 
    public void run(){ 
     Random rand = new Random(); 
     try { 
      Thread.sleep(200*rand.nextInt(10)); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(myClass.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     if (stop == false) 
      submitValue(1); 
    } 
    void Stop(){ 
     stop = true; 
    } 
} 

requestValue機能です:

void requestValue(){ 
    myThread thread = new myThread(); 

    Timer myTimer = new Timer(1000 , new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       thread.Stop(); 
       submitValue(-1); 
      } 
     }  
    ); 
    myTimer.setRepeats(false); 
    myTimer.start(); 
    thread.start(); 
} 

submitValue機能は現在だけを印刷パラメータ(1または-1)を外します。

これにより、制限時間を超えたときに関数submitValue(1)が呼び出されないようにしますが、常にsubmitValue(-1)が呼び出されます。 submitValue(1)が呼び出されたかどうかを聴取者に知らせるにはどうしたらいいですか?そして、私が使っている方法よりもこれを行う良い方法がありますか?

もう1つの問題は、すべて-1の前にすべて1が印刷されているということです。なぜそれが起こっていますか?

ありがとう

答えて

2

いくつかのこと。まず、スレッドを拡張しないでください。必要に応じて匿名で実行できるRunnableを実装し、それをThreadコンストラクタに渡します。

第2に、2番目のタイマースレッドを作成しないでください。それはあまりにも複雑で、おそらくあなたの問題の根源です。代わりに、メインスレッドブロックしてみましょう。

タイムアウトを行うには、Thread.join(long millis)を使用します。スレッドがまだアクティブな場合は、「停止」フラグを設定します。 (volatileを指定すると、ワーカースレッドは値が変更されたことを確実に確認できます)、-1を返します。それ以外の場合は、計算された値を返します。