首页 > 编程语言 >java 线程池中 execute 和 submit 方法的区别

java 线程池中 execute 和 submit 方法的区别

时间:2022-12-03 23:37:25浏览次数:60  
标签:execute task java request submit new public


ThreadPoolExecutor UML类图

java 线程池中 execute 和 submit 方法的区别_System

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方法。


标签:execute,task,java,request,submit,new,public
From: https://blog.51cto.com/u_15891990/5908782

相关文章

  • Java8 在流处理中使用集合索引号
    代码publicclassAnswerApp{publicstaticvoidmain(String[]args){List<String>list=Lists.newArrayList("Answer","AnswerAIL","AI");List......
  • Guava Google 核心 Java 类库使用总结
    jar包依赖<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>28.0-jre</version></dependency> Joiner&&Splitterp......
  • HyperLedger/Fabric 快速上手优化版 fabric-sdk-java
    文章目录​​1.前言​​​​2.前置条件​​​​3.区块链网络修改​​​​4.SDK操作步骤​​​​5.transaction.proto​​​​6.相关网址​​1.前言   由于fabri......
  • Java lang
    目录lang1.System标准输入、标准输出和错误输出流访问外部定义的属性和环境变量2.Enum3.ThrowableErrorExceptionReturn与finally的执行顺序4.类型、值和变量5.String字......
  • Java实现MySQL binlog日志监听
    使用案例引入maven依赖<dependency><groupId>com.github.shyiko</groupId><artifactId>mysql-binlog-connector-java</artifactId><version>0.21.0</version></......
  • Java8中Collectors求和功能的自定义扩展
    业务中需要将一组数据分类后收集总和,原本可以使用Collectors.summingInt(),但是我们的数据源是BigDecimal类型的,而Java8原生只提供了summingInt、summingLong、summingDouble......
  • java二维数组
    本文介绍java中二维数组的存放位置int[][]arr=newint[2][3];jvm存放二维数组的图示:下面介绍列数不明确的情况: 代码如下:publicclassTwo{publicsta......
  • [Javascript Performance] Optimisation and deoptimization
    Theoptimizingcompileroptimizesforwhatit’sseen.Ifitseessomethingnew,that’sproblematic. Seletingpropertieshassomestrangeimplicationsonpe......
  • [Javascript Performance] How to benchmark code performance
    Code:benchmark.jsconst{performance}=require('perf_hooks');//SETUP......
  • Jenkins+GitLab实现构建JAVA代码
    目录一、前置环境配置二、创建一个maven任务需要提前部署完成Jenkins+GitLab+maven可以参考我的其他文章进行部署一、前置环境配置1、安装MavenIntegration插件Jenki......