아래 편집자는 ThreadPoolExecutor 스레드 풀의 제출 방법에 대해 간략하게 설명합니다. 에디터가 꽤 좋다고 생각해서 지금 공유해서 참고용으로 올려보겠습니다. 에디터 따라가서 함께 살펴볼까요
jdk1.7.0_79
스레드 풀 ThreadPoolExecutor의 원리는 이전 글 "ThreadPoolExecutor 스레드 풀 원리와 실행 방법"에서 언급한 적이 있습니다. " 및 해당 실행 방법입니다. 이 기사에서는 ThreadPoolExecutor#submit을 분석합니다.
작업을 실행하려면 결과를 반환할 필요가 없지만 실행 결과를 반환해야 하는 경우가 있습니다. 스레드의 경우 결과를 반환할 필요가 없으면 Runnable을 구현할 수 있고, 결과를 실행해야 하는 경우 Callable을 구현할 수 있습니다. 스레드 풀에서 실행은 결과를 반환할 필요가 없는 작업 실행도 제공하며, 결과를 반환해야 하는 작업의 경우 submit 메서드를 호출할 수 있습니다.
ThreadPoolExecutor의 상속 관계를 검토하세요.
Executor 인터페이스에는 실행 메소드만 정의되어 있고, ExecutorService 인터페이스에는 submit 메소드가 정의되어 있습니다.
//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을 구현하는 스레드에는 반환 값이 없습니다. 즉, 위의 세 가지 메서드 중에서 submit(Callable
다음은 제출 방법에 대한 느낌을 얻을 수 있는 3가지 예입니다.
submit(Callable
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(Generics), 의 차이점"을 참조하세요.)
위의 소스 코드에서 세 가지 메서드가 거의 동일하다는 것을 알 수 있습니다. 핵심은 다음과 같습니다.
RunnableFuture<T> ftask = newTaskFor(task); execute(ftask);
작업을 newTaskFor에 매개 변수로 전달한 다음 실행 메서드를 호출하고 마지막으로 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는 이 두 인터페이스를 구현합니다. 이는 비동기 계산의 결과를 나타내고 실행을 위한 스레드로 Executor에 전달될 수 있음을 의미합니다. FutureTask는 다음 장에서 별도로 분석됩니다. 따라서 스레드 풀 ThreadPoolExecutor 스레드 풀의 제출 메소드에 대한 이 기사의 분석은 완료되지 않았습니다. Java 스레드의 미래 모드 - "Java의 미래 모드에 대한 진부한 표현"을 이해해야 합니다.
위 내용은 JAVA의 ThreadPoolExecutor 스레드 풀 제출 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!