ホームページ  >  記事  >  Java  >  JAVAのThreadPoolExecutorスレッドプールのsubmitメソッドの詳細説明

JAVAのThreadPoolExecutorスレッドプールのsubmitメソッドの詳細説明

怪我咯
怪我咯オリジナル
2017-06-30 10:43:164680ブラウズ

次のエディタでは、ThreadPoolExecutor スレッド プールの submit メソッドについて簡単に説明します。編集者はこれがとても良いものだと思ったので、皆さんの参考として今から共有します。編集者をフォローして一緒に見てみましょう

jdk1.7.0_79

ThreadPoolExecutorの原理については、前回の記事『ThreadPoolExecutorスレッドプールの原理とその実行方法』で触れました。 」とその実行メソッド。この記事では ThreadPoolExecutor#submit を分析します。

タスクの実行では、結果を返す必要がない場合もありますが、実行結果を返す必要があります。スレッドの場合、結果を返す必要がない場合は Runnable を実装でき、結果を実行する必要がある場合は Callable を実装できます。スレッド プールでは、execute は結果を返す必要のないタスクの実行も提供します。結果を返す必要があるタスクについては、その submit メソッドを呼び出すことができます。

ThreadPoolExecutor の継承関係を確認します。

Executor インターフェースには実行メソッドのみが定義され、送信メソッドは ExecutorService インターフェースに定義されます。

//ExecutorService
public interface ExecutorService extends Executor {
  ...
  <T> Future<T> submit(Callable<T> task);
  <T> Future<T> submit(Runnable task, T result);
  <T> Future<T> submit(Runnable task);
  ...
}

submit メソッドはそのサブクラス AbstractExecutorService に実装されています。

//AbstractExecutorService
public abstract class AbstractExecutorService implements ExecutorService {
  ...
  public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
  }
  public <T> Future<T> submit(Runnable task, T result) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
  }
  public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerExeption();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask; 
  }
  ...
}

AbstractExecutorService に実装されている submit メソッドは、実際には submit メソッドのアルゴリズム スケルトンを定義するテンプレート メソッドであり、その実行はサブクラスに渡されます。 (テンプレートメソッドのパターンは多くのソースコードで広く使われていることがわかります。テンプレートメソッドのパターンについては「テンプレートメソッドのパターン」を参照してください。)

submitメソッドはスレッド実行の戻り値を提供できますが、 Callable が実装されている場合にのみ戻り値が返され、Runnable を実装するスレッドには戻り値がありません。つまり、上記の 3 つのメソッドのうち、submit(Callable8742468051c85b06f0a0af9e3e506b5c task) は戻り値を取得でき、submit(Runnable task) は戻り値を持ちません。 、T 結果) が可能です。スレッドの戻り値は、受信キャリア結果を通じて間接的に取得されます。正確には、最後のメソッドである submit (実行可能なタスク) には戻り値がなく、さらには処理のためにスレッドに渡されます。取得した場合、戻り値は null です。

submit メソッドの雰囲気をつかむための 3 つの例を以下に示します。

submit(Callable8742468051c85b06f0a0af9e3e506b5c task)

package com.threadpoolexecutor;

import java.util.concurrent.*;

/**
 * ThreadPoolExecutor#sumit(Callable<T> task)
 * Created by yulinfeng on 6/17/17.
 */
public class Sumit1 {

 public static void main(String[] args) throws ExecutionException, InterruptedException {
 Callable<String> callable = new Callable<String>() {
 public String call() throws Exception {
 System.out.println("This is ThreadPoolExetor#submit(Callable<T> task) method.");
 return "result";
 }
 };

 ExecutorService executor = Executors.newSingleThreadExecutor();
 Future<String> future = executor.submit(callable);
 System.out.println(future.get());
 }
}

submit(Runnable task, T result)

package com.threadpoolexecutor;

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

/**
 * ThreadPoolExecutor#submit(Runnable task, T result)
 * Created by yulinfeng on 6/17/17.
 */
public class Submit2 {

 public static void main(String[] args) throws ExecutionException, InterruptedException {

 ExecutorService executor = Executors.newSingleThreadExecutor();
 Data data = new Data();
 Future<Data> future = executor.submit(new Task(data), data);
 System.out.println(future.get().getName());
 }
}

class Data {
 String name;

 public String getName() {
 return name;
 }

 public void setName(String name) {
 this.name = name;
 }
}

class Task implements Runnable {
 Data data;

 public Task(Data data) {
 this.data = data;
 }
 public void run() {
 System.out.println("This is ThreadPoolExetor#submit(Runnable task, T result) method.");
 data.setName("kevin");
 }
}

submit(Runnable task)

package com.threadpoolexecutor;

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

/**
 * ThreadPoolExecutor#sumit(Runnable runnables)
 * Created by yulinfeng on 6/17/17.
 */
public class Submit {

 public static void main(String[] args) throws ExecutionException, InterruptedException {
 Runnable runnable = new Runnable() {
 public void run() {
 System.out.println("This is ThreadPoolExetor#submit(Runnable runnable) method.");
 }
 };

 ExecutorService executor = Executors.newSingleThreadExecutor();
 Future future = executor.submit(runnable);
 System.out.println(future.get());
 }
}

上記の例から、 submit( Runnable runnable) の場合、その定義された型は必要ありません。つまり、ExecutorService で定義されたジェネリック メソッドですが、戻り値がないため、AbstractExecutorService ではジェネリック メソッドではありません。 (Object、T、?の違いについては「JavaにおけるObject、T(ジェネリック)、の違い」を参照してください。)

上記のソース コードから、3 つのメソッドがほぼ同じであることがわかります。重要な点は次のとおりです。

RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);

newTaskFor にパラメーターとしてタスクを渡し、execute メソッドを呼び出し、最後に ftask を返す方法。

//AbstractExecutorService#newTaskFor
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
  return new FutureTask<T>(callable);
}
  protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
  return new FutureTask<T>(runnable, value);
}

FutureTaskインスタンスが返されるようで、FutureTaskはFutureインターフェースとRunnableインターフェースを実装しています。 Future インターフェイスは、非同期計算に使用できる Java スレッド Future モードの実装です。Runnable インターフェイスを実装すると、スレッドとして実行できるようになります。 FutureTask はこれら 2 つのインターフェイスを実装しています。これは、非同期計算の結果を表し、実行用のスレッドとして Executor に渡すことができることを意味します。 FutureTask については、次の章で個別に分析します。したがって、この記事のスレッド プール ThreadPoolExecutor スレッド プールの submit メソッドの分析は完全ではありません。Java スレッドの Future モード (「Java の Future モードについての決まり文句」) を理解する必要があります。

以上がJAVAのThreadPoolExecutorスレッドプールのsubmitメソッドの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。