92

タスクExectorServiceをプールして送信する方法を学んでいます。threads以下に簡単なプログラムがあります

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


class Processor implements Runnable {

    private int id;

    public Processor(int id) {
        this.id = id;
    }

    public void run() {
        System.out.println("Starting: " + id);

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            System.out.println("sorry, being interupted, good bye!");
            System.out.println("Interrupted " + Thread.currentThread().getName());
            e.printStackTrace();
        }

        System.out.println("Completed: " + id);
    }
}


public class ExecutorExample {

    public static void main(String[] args) {
        Boolean isCompleted = false;

        ExecutorService executor = Executors.newFixedThreadPool(2);

        for (int i = 0; i < 5; i++) {
            executor.execute(new Processor(i));
        }

        //executor does not accept any more tasks but the submitted tasks continue
        executor.shutdown();

        System.out.println("All tasks submitted.");

        try {
            //wait for the exectutor to terminate normally, which will return true
            //if timeout happens, returns false, but this does NOT interrupt the threads
            isCompleted = executor.awaitTermination(100, TimeUnit.SECONDS);
            //this will interrupt thread it manages. catch the interrupted exception in the threads
            //If not, threads will run forever and executor will never be able to shutdown.
            executor.shutdownNow();
        } catch (InterruptedException e) {
        }

        if (isCompleted) {
            System.out.println("All tasks completed.");
        } else {
            System.out.println("Timeout " + Thread.currentThread().getName());
        }
    }
}

特別なことは何もしませんが、2 つのタスクを作成threadsし、合計で 5 つのタスクを送信します。それぞれthreadがタスクを完了すると、次のタスクが実行されます。上記のコードでは、 を使用していますexecutor.submit。にも変更しましたexecutor.execute。しかし、出力に違いは見られません。submitexecuteメソッドの違いは何ですか? これがAPI言うこと

メソッド submit は、基本メソッド Executor.execute(java.lang.Runnable) を拡張し、実行をキャンセルしたり、完了を待機したりするために使用できる Future を作成して返します。メソッド invokeAny および invokeAll は、タスクのコレクションを実行してから、少なくとも 1 つまたはすべてのタスクが完了するまで待機する、最も一般的に有用な形式の一括実行を実行します。(クラス ExecutorCompletionService を使用して、これらのメソッドのカスタマイズされたバリアントを作成できます。)

しかし、それが正確に何を意味するのか、私には明らかではありませんか?

4

8 に答える 8

79

JavaDoc からわかるように、execute(Runnable)何も返されません。

ただし、実行中のスレッドを後でプログラムでキャンセルしたり、完了時に返される を取得したりする方法を可能submit(Callable<T>)にするオブジェクトを返します。詳細については、将来の JavaDoc を参照してください。FutureTCallable

Future<?> future = executor.submit(longRunningJob);
...
//long running job is taking too long
future.cancel(true);

さらに、future.get() == null例外がスローされない場合、Runnable は正常に実行されました

于 2013-09-10T23:32:11.693 に答える
55

違いは、タスクを管理するためにオブジェクトを返すのexecuteに対し、それ以上苦労することなくタスクを開始することです。オブジェクトを使用して次のことができます。submitFutureFuture

  • メソッドを使用して、タスクを時期尚早にキャンセルしますcancel
  • で、タスクの実行が完了するまで待ちますget

をプールに送信すると、Futureインターフェイスがより便利Callableになります。を呼び出すと、メソッドの戻り値callが返されますFuture.get。への参照を維持しない場合Future、違いはありません。

于 2013-09-10T23:31:38.727 に答える
31

execute:ファイア アンド フォーゲット コールに使用する

submit:これを使用してメソッド呼び出しの結果を検査しFuture、呼び出しによって返されたオブジェクトに対して適切なアクションを実行します

主な違い:Exception取り扱い

submit()Exceptionフレームワーク自体で未処理を非表示にします。

execute()unhandled をスローしExceptionます。

で例外を処理するためのソリューションsubmit()

  1. あなたのラップCallable or Runnable code in try{} catch{} block

    また

  2. 保つfuture.get() call in try{} catch{} block

    また

  3. ThreadPoolExecutor独自のオーバーライドafterExecuteメソッドを実装する

ツアーに関するその他のお問い合わせについて

すべての呼び出し:

指定されたタスクを実行し、ステータスと結果を保持する Future のリストを返します。

任意の呼び出し:

指定されたタスクを実行し、指定されたタイムアウトが経過する前に正常に完了した (つまり、例外をスローせずに) 完了したタスクの結果を返します。

invokeAll送信されたすべてのタスクが完了するまで待機する場合に使用します。

invokeAny送信された N 個のタスクのうち 1 つのタスクを正常に完了することを探している場合に使用します。この場合、タスクの 1 つが正常に完了すると、進行中のタスクはキャンセルされます。

コード例を含む関連記事:

ExecutorService の送信と ExecutorService の実行のどちらかを選択します

于 2016-08-23T15:27:08.943 に答える
5

Submit - 送信されたタスクの結果を確認するために使用できる Future オブジェクトを返します。キャンセルや isDone の確認などに使用できます。

実行 - 何も返しません。

于 2015-07-08T12:47:36.380 に答える
4

ソースコードを確認すると、それsubmitが一種のラッパーであることがわかりますexecute

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}
于 2019-03-04T02:38:46.743 に答える