2つの操作を実行する必要がある関数があります。1つは速く終了し、もう1つは実行に長い時間がかかります。実行時間の長い操作をスレッドに委任したいのですが、スレッドがいつ終了するかは気にしませんが、スレッドは完了する必要があります。以下に示すようにこれを実装しましたが、start()呼び出しの後に関数が終了するため、2番目の操作は完了しません。関数が確実に戻るが、2番目の操作スレッドもその実行を終了し、親スレッドに依存していないことを確認するにはどうすればよいですか?
public void someFunction(String data)
{
smallOperation()
SecondOperation a = new SecondOperation();
Thread th = new Thread(a);
th.Start();
}
class SecondOperation implements Runnable
{
public void run(){
// doSomething long running
}
}
_public void someFunction(final String data) {
shortOperation(data);
new Thread(new Runnable() {
public void run(){
longOperation(data);
}
}).start();
}
_
someFunction
が呼び出された場合、JVMはlongOperation
を実行します。
longOperation()
は例外をスローせず、longOperation()
ではSystem.exit()への呼び出しは行われませんスレッドが終了するまでJVMは終了しません。あなたが投稿したこのコードはコンパイルさえしません。おそらく問題はあなたの実際のコードにあります。
2番目の関数が完了していない場合、関数の戻りとは関係ありません。何かがSystem.exit()
を呼び出した場合、または関数が例外をスローした場合、スレッドは停止します。それ以外の場合は、メインスレッドが停止した場合でも、完了するまで実行されます。新しいスレッドをデーモンに設定することでそれを防ぐことができますが、ここではそうしていません。
私があなたの質問を正しければ、someFunction()
を呼び出し、短いsmallOperation()
を実行し、SecondOperation
へのスレッドを実行し、この関数から返されたときに、 SecondOperation
が完了しました。
私が提案したフローが正しい場合、次の行を追加するだけで済みます:
public void someFunction(String data)
{
smallOperation()
SecondOperation a = new SecondOperation();
Thread th = new Thread(a);
th.Start();
th.join(); //add this line to make your MainThread await for this to finish .
}
class SecondOperation implements Runnable
{
public void run(){
// doSomething long running
}
}
これを見てみましょう article は、「スレッドでjoin()メソッドを呼び出すと、呼び出し元のスレッドは待機状態になります。参照されたスレッドが終了するまで待機状態のままです。 」あなたが達成しようとしていること
そうでない場合、SecondOperation
が終了したときに通知を受け取りたい場合は、 asyncTask を使用することをお勧めします
modern Javaを使用したソリューション
public void someFunction(String data) {
smallOperation();
new Thread(() -> {
// doSomething long running
}).start();
}
この質問に答えるのは遅いかもしれませんが、これが実際の解決策です。実行可能ファイルをExecutorServiceに追加するだけです。
import Java.util.concurrent.ExecutorService;
import Java.util.concurrent.Executors;
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.execute(new Runnable() {
@Override
public void run() {
//your code
}
});