質問

次のJavaコードがあります:

final Future future = exeService.submit(
    new Runnable() {
        public void run() {
            myObject.doSomething();
        }
    }
);

future.get();

どこ exeService のインスタンスです

java.util.concurrent.ExecutorService

問題はそれです myObject.doSomething() 決して戻ってこない、そして、したがって、 future.get() 返さないでください。

ただし、通話を交換する場合 submit 電話があります execute このような:

exeService.execute(
    new Runnable() {
        public void run() {
            myObject.doSomething();
        }
    }
);

通話 myObject.doSomething() 戻ってきます。それが重要かどうかはわかりませんが doSomething() aです void 方法。

なぜそうなのか doSomething() 使用するときに仕上げます execute しかし、使用するときではありません submit?

また、使用する必要はありません Future.get();それはこれを行う最も自然な方法のように思えました。 (私も同じ問題に遭遇します CountdownLatch。)ポイントは、私が待つ必要があるということです doSomething() 先に進む前に終了するには、複雑な理由でここには入らないので、別のスレッドで起動する必要があります。これを行う別の方法が機能する場合、それは問題ありません。

役に立ちましたか?

解決

のように executor.execute()javadoc:

将来のある時点で指定されたコマンドを実行します。コマンドは、新しいスレッド、プールされたスレッド、または執行者の実装の裁量で、呼び出しスレッドで実行できます。

したがって、メソッド execute() すぐに返品すると、提出されたタスクのステータスに照会するオプションがありません。

一方で executorservice.submit():

実行可能な実行可能なタスクを提出し、そのタスクを表す未来を返します。将来のGETメソッドは、正常に完了するとnullを返します。

future.get() 戻ります それだけ 競争が成功した後、そう 一度もない あなたの場合。

これはさらに注目されています future.get()ドキュメント:

必要に応じて計算が完了するまで待機してから、結果を取得します。

他のヒント

私は作成しました sscce:

package com.stackoverflow.q2585971;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Test {

    public static void main(String args[]) throws Exception {
        ExecutorService executor = Executors.newCachedThreadPool();
        Future<?> future = executor.submit(
            new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        System.out.println("Epic fail.");
                    }
                }
            }
        );

        System.out.println("Waiting for task to finish..");
        future.get();
        System.out.println("Task finished!");
        executor.shutdown();
    }

}

それは完全に正常に機能します。最初に印刷します

Waiting for task to finish..

その後、1秒後に表示されます

Task finished!

ですから、あなたの問題はどこかにあります。ここであなたの質問に対する私のコメントを複製します:

あなたの質問はかなり混乱しています。最初のコンストラクトは機能するだけです。混乱は「戻る」ことです。 「仕上げ」や「実行」を意味するだけではありませんか?あなたの混乱はその事実に基づいているようです future.get() 実際に、実行可能が完了するのを待つため、スレッドがブロックされ、後にコードの残骸が実行されるのを防ぎます future.get() ライン。

Java Futuresがブロックしています! get(). This method blocks the current thread until a future instance completes its work, thus requiring the use of one thread more than the work that must be performed just to manage what happens when it is done

デッドロックを確認してください doSomething.

私は探すことから始めます wait 電話。

もし、あんたが wait 何かについては、呼び出して他のスレッドから待っているオブジェクトを信号する必要があります notify また notifyAll.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top