次のエディタでは、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 サイトの他の関連記事を参照してください。