2016-10-13 12 views
0

今私はJavaFxタスクをスレッド内でバックグラウンドプロセスとして使用しています。JavaFxは素早くバックグラウンドタスクを停止します

Task<Void> task = new Task<Void>(){ 
    @Override 
    protected Void call() throws Exception { 
     while(running){ 
      doSomething(); 
     } 
     saveData(); 
     return null; 
    } 
}; 
Thread th = new Thread(task); 
th.start(); 

私は(私は= falseを実行している設定することで、プロセスを停止したいという意味できるだけスムーズ、このプロセスを停止したいと思います。可能な限り保存()メソッドを呼び出して、私が欲しい、同時にこれと。 JavaFxプロセス(ウィンドウ)が閉じられた後、バックグラウンドプロセスが実行され続ける機会がないことを確認してください。

現時点では、スレッドをDeamonとして設定して、JavaFxプロセスデッド(2つのプロセスだけが実行中のプロセスです)

th.setDeamon(true); 
私は私の唯一のステージ

stage.setOnCloseRequest(e -> running = false); 

にCloseRequestListenerを追加しました。同時に0

は今私の質問:プロセスがデーモンであるので

は、それが実行の途中で削除することができます。 JavaFxプロセスが終了した後、バックグラウンドタスクが確実に終了するようにする良い方法はありますか? (たとえJavaFxプロセスが強制終了されたとしても)

デーモンスレッドを円滑に終了させる方法はありますか?

編集:私の主な優先事項は、バックグラウンドスレッドが生き残ることができないということです。また、2番目の優先順位は、バックグラウンドスレッドができるだけスムーズに強制終了されることです。

答えて

3

Taskすでにキャンセル機構を備えているので、あなたはvolatileを作るために注意する必要がありrunningフラグ(でこれを自分で実装する必要がない、または1つのスレッドからそれに必ず変更を加えるために他の方法を使用するが表示されます別のもので)。

はそうちょうど行います

Task<Void> task = new Task<Void>(){ 
    @Override 
    protected Void call() throws Exception { 
     while(! isCancelled()){ 
      doSomething(); 
     } 
     saveData(); 
     return null; 
    } 
}; 

あなたdoSomething()方法は、タスクにcancel()を呼び出すと、そのスレッドが中断されるように、例外をキャッチしてください、InterruptedException Sをスローする可能性があります呼び出しをブロックが含まれる場合:

Task<Void> task = new Task<Void>(){ 
    @Override 
    protected Void call() throws Exception { 
     while(! isCancelled()){ 
      try { 
       doSomething(); 
      } catch (InterruptedException exc) { 
       if (isCancelled()) { 
        break ; 
       } 
      } 
     } 

     saveData(); 
     return null; 
    } 
}; 

最後に、あなたのステージでsetOnCloseRequest()に頼るべきではありません。外部コールが閉じると呼び出される場合にのみ呼び出されます。ウィンドウ(例:ユーザはネイティブウィンドウクローズボタンを押す)。たとえば、Platform.exit()に電話すると、それは実行されません。 ?stop()メソッドが例外なしに呼び出されます場合は、あなたが知っている)=ありがとう

@Override 
public void stop() { 
    task.cancel(); 
} 
+0

ああ:代わりに、Application.stop()メソッドをオーバーライドもし私がスレッドをデアモンとして保持していれば、それはdoSomething()の途中で強制終了することができます。また、あなたが言及したように、cancle()呼び出しは途中でdoSomething()を破る可能性のある中断された例外をスローする可能性があります。私はできるだけそれを防止したいと思います。たとえば、データを変更して複数のファイルに書き込むと、プロセスが途中で停止した場合、データが不安定になる可能性があります。 –

+0

これは、 'doSomething()'が割り込み可能な呼び出しをブロックしている場合にのみ問題になります。 'stop()'は 'System.exit()'で終了しない限り呼び出されます(これは単にすべてのスレッドを終了させるため、呼び出していない以外は回避する方法はありません)。 –

関連する問題