2012-03-20 28 views
0

私はここの机の上の机と私の頭を叩いています。これが私が達成しようとしていることです。私は新しいスレッドを作成するメインクラスを持っています。現在、スレッドが正常に終了すると、それはマイナーなクリーンアップを行い、スレッドは停止します。しかし、私はUI上に「停止」ボタンがあり、押されたときには「クリーンアップしてからスレッドを終了する」必要があります。問題は、私が作成した新しいスレッドの中にあるものは更新できないようですここでJava - メインクラスの実行可能ファイルを停止できません

がいくつか抜粋です:上記のコードで

メインクラス

runner = new Thread(new Controller1(options)); 
runner.start(); 

、私は私のController1クラスを呼び出して、コンストラクタでいくつかの「オプション」を設定しています。これは良い取り組んでいます。これまでのところ...

ここで、Controller1クラスでは、これはwhaです私は...

public volatile static boolean stopped; 

public void run() { 
    while(!stopped){ 
     System.out.println("In run"); 
     startProxy(proxyPort); 
     startWebDriver(); 
     driver.get(http); 
     UIMainJSwing1.updateStartButton(); 
     stopped=true; 
    } 

    //Run killAll to stop webdriver and the proxy 
    killAll(); 
    System.out.println("Thread complete"); 
} 

問題は、メインクラスから、私は呼び出すことはできませんまたは "停止"をtrueに設定します。私はrunner.interrupt()を呼び出すことができますが、問題は、スレッドが死ぬだけで、killAll()関数は実行されていないため、WebDriverとProxyを実行したままです。

+0

Whileループの良い点は、メインからこのスレッドを停止する方法を見つけようとしていたので、そこに配置したと思います。これで私はそれを削除しました。はい、それは一度実行されましたが、run()メソッドとkillAll()に取り消すオーバーライドを持つことはありますか? – Whnunlife

+0

そのループ内の呼び出しをブロックしていますか? – Tudor

+0

@Whnunlifeあなたが何か助けになることが分かったら、あなたはそれをアップヴォートするか、またはそれを受け入れるべきです。グレイの答え。 –

答えて

1

私はあなたのメインスレッドでthread.interupt()に電話をかけて、自分のkillAll()メソッドが呼び出されたことを確認するために、Runnableにループの周りtry/finally blockを使用します。

public void run() { 
    try { 
     while (!stopped) { 
      ... 
     } 
    } finally { 
     //Run killAll to stop webdriver and the proxy 
     killAll(); 
     System.out.println("Thread complete"); 
    } 
} 

finallyブロックは常にが呼び出されます。スレッドが中断されたり、例外がスローされた場合でも

カップル他のコメント:

そして、あなたはvolatile boolean stoppedフラグを言及しかし、あなたはすべてのループを持っている理由私が見るんので、ループの最後で、すぐに真であることがその設定されています。

スレッドが実行されず、即座にkillAll()を呼び出すと仮定すると、メソッドのいずれかにぶら下がっています。メインスレッドからinterrupt()を呼び出すと、待っているものはInterruptedExceptionになります。しかし、私は何も起こっていないので、おそらく方法はRuntimeExceptionとしてそれを投げているのでしょうか?彼らは、少なくとも以下のようなものをやってますが、このまだブロックされなければならない例外:

try { 
    something.wait(); 
} catch (InterruptedException e) { 
    // restore the interrupted condition 
    Thread.currentThread().interrupt(); 
} 

かかわらず、試しては/ついにkillAllが呼び出されたことを確認するために行くための正しい方法です。

+0

'catch(InterruptedException e){ //中断した状態を復元します。 Thread.currentThread()。interrupt(); } 'これは何らかの' while(true) 'ループに入っていれば、まだ例外を食べている可能性があります – artbristol

+0

True @artbristol。私は私の答えを微調整しました。ありがとう。 – Gray

+0

質問、このtry/catchは、私のrunnableのrun()メソッドに入るはずですか? – Whnunlife

0

まず、あなたのkillAll()メソッドが実行されるように、おそらくInterruptedExceptionをキャッチする必要があります。 try/finallyを使用するだけです。

次に、mainメソッドからstopped = trueを設定できないのはなぜですか?

+0

私はそれを試しました。だから私はそれをテストするために、run()の中にあった、whileステートメントの終わりでstopped = trueを削除します。だから、もし私がそれを実行すると、それは単なるループに過ぎません。それからボタンをクリックするとMainからその値を設定しようとしましたが、ループは終了しません。 – Whnunlife

+0

"中断"を使用するコードを調べると、run()メソッドで中断されたかどうかを調べる== trueで、InterruptedExceptionをスローします。ちょうどあなたの停止に似て==真。 重要な点は、あなたは決して別のスレッドから強制的に実行中のスレッドに割り込むことができないということです。実行をまだ実行する必要がある場合は、いつでもrun()でコードをチェックインする必要があります。そうでない場合は、終了するか、InterruptedExceptionをスローします。すべて自分で:) スレッドのクラスに存在するisInterrupted()メソッドを使用し、メインスレッドからinterrupt()を呼び出すことはできません。 – yggdraa

+0

情報をありがとうので、私は基本的に(!isInterrupted())を持っている必要があります次に、私はthread.interruptを呼び出すと、それは本当のようにチェックを取得し、 – Whnunlife

0

私はあなたが間違っていると理解したら、while(!stopped)イディオムを誤用します。あなたのコードでは、一度停止していないかどうかをチェックし、最後まですべてを行い、stopped = trueを設定して終了します。実行した後に実行を停止するチャンスを与えないだけです。それが開始されると、停止したフィールドは、それが終わるまで再び黙認されません。

+0

あなたは正しいです、今すぐ対応してください! – Whnunlife

0

まず、while(!stopped)stopped=true部分を失ってください。 またスレッド内の別々の段階でstoppedを評価する必要があります(killAll()を実行して、もちろん開始ボタンを再度有効にしてください)。

+0

私はrun()メソッドを変更し、各関数をif(!stopped)にラップしました。つまり、メインからstopped = trueを設定すると、次の関数は実行されず、killAllが呼び出されます。私はそれが働いていると思う、アマチュアコードのように見えるが、ああ。 – Whnunlife

関連する問題