ThreadPoolExecutor UML类图
execute 方法定义
public interface Executor {
void execute(Runnable command);
}
submit 方法定义
public interface ExecutorService extends Executor {
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
}
submit 方法具体实现
public abstract class AbstractExecutorService implements ExecutorService {
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
}
execute 方法具体实现
public class ThreadPoolExecutor extends AbstractExecutorService {
public void execute(Runnable command) {
// 具体实现
}
}
程序验证
public class ExecuteVsSubmit {
public static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
// 线程池核心线程最大线程数
private static final int MAX_THREAD_SIZE = 10;
public static void main(String[] args) throws Exception {
// 模拟请求列表
List<String> requests = Lists.newArrayList("A0001", "A0002", "A0003", "A0004", "A0005", "B0001", "B0002", "B0003", "B0004", "B0005");
ExecutorService executor = Executors.newFixedThreadPool(requests.size() > MAX_THREAD_SIZE ? MAX_THREAD_SIZE : requests.size());
// 只在 submit 方式-2 和 submit 方式-3 中用到
List<Future<Response>> futures = new ArrayList<>();
System.out.println(SDF.format(new Date()) + " 发送请求~~~");
for (String request : requests) {
// execute 方式 (第二个参数意义不大, 可以参考 `submit 方式-2-2` 的调用方式)
// executor.execute(new TaskRunnable(request, new Response()));
// submit 方式-1 (第二个参数意义不大, 可以参考 `submit 方式-2-2` 的调用方式)
// executor.submit(new TaskRunnable(request, new Response()));
// submit 方式-2-1
// Response response = new Response();
// Future<Response> future = executor.submit(new TaskRunnable(request, response), response);
// futures.add(future);
// submit 方式-2-2
Response response = new Response();
Future<Response> future = executor.submit(() -> {
System.out.println(String.format("%s 异步请求接口=[%s]",
ExecuteVsSubmit.SDF.format(new Date()), request));
try {
Thread.sleep(5 * 1000);
response.setMsg(request);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, response);
futures.add(future);
// submit 方式-3
// Future<Response> future = executor.submit(new TaskCallable(request));
// futures.add(future);
}
// 获取异步结果
for (Future<Response> future : futures) {
System.out.println(SDF.format(new Date()) + " 结果=" + future.get().getMsg());
}
executor.shutdown();
}
}
class TaskCallable implements Callable<Response> {
private String request;
public TaskCallable(String request) {
this.request = request;
}
@Override
public Response call() throws Exception {
System.out.println(String.format("%s 异步请求接口=[%s]",
ExecuteVsSubmit.SDF.format(new Date()), this.request));
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Response(request);
}
}
class TaskRunnable implements Runnable {
private String request;
private Response response;
public TaskRunnable(String request, Response response) {
this.request = request;
this.response = response;
}
@Override
public void run() {
System.out.println(String.format("%s 异步请求接口=[%s]",
ExecuteVsSubmit.SDF.format(new Date()), this.request));
try {
Thread.sleep(5 * 1000);
response.setMsg(request);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Response {
private String msg;
}
- execute和submit都属于线程池的方法,execute只能提交Runnable类型的任务,而submit既能提交Runnable类型任务也能提交Callable类型任务。
- execute会直接抛出任务执行时的异常,submit会吃掉异常,可通过Future的get方法将任务执行时的异常重新抛出。
- execute所属顶层接口是Executor,submit所属顶层接口是ExecutorService,实现类ThreadPoolExecutor重写了execute方法,抽象类AbstractExecutorService重写了submit方法。