6

私は次の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()が、void方法です。

使用時に終了するのに、使用しないときにdoSomething()終了するのはなぜですか?executesubmit

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

4

4 に答える 4

18

Executor.execute() Javadocのように:

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

そのため、メソッドexecute()はすぐに返され、送信されたタスクのステータスを照会するオプションはありません。

一方、ExecutorService.submit() :

Runnable タスクを実行のために送信し、そのタスクを表す Future を返します。Future の get メソッドは、正常に完了すると null を返します。

Future.get()は、競合が成功した後にのみ返されるため、あなたの場合は決して返されません。

これは、Future.get() のドキュメントにさらに記載されています。

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

于 2010-04-06T15:23:05.137 に答える
8

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();
    }

}

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

タスクが完了するのを待っています..

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

任務終了!

したがって、あなたの問題は別の場所にあります。ここであなたの質問に対する私のコメントを複製します:

あなたの質問はかなり混乱しています。最初の構成は機能するはずです。混乱は「戻る」にあります。「仕上げる」とか「実行する」だけじゃないの?あなたの混乱はfuture.get() 、実行可能ファイルが終了するのを実際に待っているため、スレッドをブロックし、future.get()行の後のコードの残りを実行できないという事実に基づいているようです。

于 2010-04-06T15:28:15.233 に答える
2

Java の先物がブロックされています! 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

于 2014-03-27T09:37:13.163 に答える
0

でデッドロックをチェックしdoSomethingます。

wait通話を検索することから始めます。

wait何かが必要な場合は、またはを呼び出して、他のスレッドから待機しているオブジェクトに通知する必要がありnotifyますnotifyAll

于 2010-04-06T15:51:32.410 に答える