ExecutorServiceとは何ですか?

正直なところ、この質問はそれほど新しいものではありません。Java 5とjava.util.concurrent。*パッケージのリリースから13年以上が経過しましたが、私の10年間の実践のすべてにおいて、私はこの獣に直面する必要はありませんでした。それにもかかわらず、私はインタビュー中に何度かこの質問をされ、知り合いにならなければなりませんでした。



当然、私が最初に始めたのはHabrです。しかし、残念ながら、ここで見つけた記事は2つだけです



。habrahabr.ru

/ post / 260953 habrahabr.ru/post/116363



最初の記事は 、明らかに、ExecutorServiceを理解していて経験がある人向けです。残念ながら、2番目は私に入りませんでした。小さくて「場合によっては」見えるのですが、何度か読み直しても、ExecutorServiceとは何か、何と一緒に食べられるのかがわかりません。そのため、Eclipseに座って、 喫煙し、 javadocを読んで、それを理解する必要がありました。



それでは、簡単な例を見てみましょう。



ExecutorService service = Executors.newFixedThreadPool(3);
service.execute(new Runnable() {
    public void run() {
        System.out.println("Another thread was executed");
    }
});

      
      





この例では、ExecutorServiceオブジェクト自体を作成し、そのオブジェクトでexecuteメソッドを呼び出しました。最も一般的なスレッド実装をそれに渡します。これはすべて古い祖父の方法で構築された可能性がありますが、これははるかに単純でエレガントです。実際、現在のスレッドから別の非同期スレッドをすばやく分岐しました。これにより、バックグラウンドで何かを実行できます。

ファクトリを使用してExecutorServiceオブジェクトを作成しました。その方法は非常に明白なので、先延ばしになりすぎないようにします。それらのいくつかを次に示します。



ExecutorService service1 = Executors.newSingleThreadExecutor();
ExecutorService service2 = Executors.newFixedThreadPool(3);
ExecutorService service3 = Executors.newScheduledThreadPool(3);

      
      





「ファイアアンドフォーゲット」の原則に基づいて呼び出されるexecuteメソッドに加えて、当社のサービスにはsubmitメソッドもあります。前者との唯一の違いは、後者がFutureインターフェースのオブジェクトを返すことです。これは、バックグラウンドで実行するスレッドの状態を制御するための優れた方法です。これは次のように行われます。



Future future = service.submit(new Runnable() {
    public void run() {
        System.out.println("Another thread was executed");
    }
});
...
future.get();

      
      





getメソッドは現在のスレッドを致命的にブロックし、バックグラウンドスレッドが終了するまで待機することに注意してください。今、あなたはこれらすべての明白でない結合を必要としません!バックグラウンドスレッドが終了しないことが心配な場合は、get(long、TimeUnit)を使用できます。



バックグラウンドスレッドから現在のスレッドにデータを返さなければならない場合があります。 submitメソッドもこれに役立ちますが、RunnableではなくCallableオブジェクトを渡す必要があります。実際、これらは2つの同一のインターフェースですが、唯一の違いは、後者が何かを返すことができるということです。



Future future = service.submit(new Callable(){
    public Object call() throws Exception {
        System.out.println("Another thread was executed");
        return "result";
    }
});
...
System.out.println("Result: " + future.get());

      
      





要するに、それだけです。ExecutorServiceを作成するメソッドでした-そしてファクトリ(多くあります)では、ExecutorServiceのメソッドであり、バックグラウンドスレッドでのエラー処理の問題でしたが、それは別の話です...



最後に忘れないでください:



servcie.shutdown();

      
      





または、すべてのバックグラウンドスレッドがデーモンである場合。



All Articles