java - ExecutorService 不起作用,但单独创建线程可以

标签 java multithreading

我有一个 REST API,我应该从外部 API 获取大量数据。我决定尝试多线程来优化整个获取-解析-持久周期。但我在 ExecutorService 方面遇到了麻烦(在这项工作之前我没有使用过它)。我正在分享整个过程的类(class)和相关部分

    public class LogRetrievingService implements Runnable {
    CustomHttpClient client;
    public LogRetrievingService(CustomHttpClient client) {
        this.client = client;
    }
    @Override
    public void run() {
        Response response = client.invokeExternalApi();
        parse(response.readEntity(bytes[].class);
    }
//skipping parse() for brevity, it basically selects some columns and sends them to DBwriter

我的REST API资源是这样的

public class LogRetrieverResource {
private CustomHttpClient client;

public LogRetrieverResource(CustomHttpClient client) {
            this.client = client;
}

//this does not work
public void initLogRetrieval() {
    ExecutorService service = Executors.newFixedThreadPool(4); //max_thread 
    for(int i = 0; i < 4; i++) {            
        service.submit(new LogRetrievingService (client));
    }
}

//THIS WORKS
public void initLogRetrieval() {
    for(int i = 0; i < 4; i++) {            
        Thread thread = new Thread(new LogRetrievingService(client));
        thread.start();
    }
}
}

现在,当我访问资源时,没有任何反应,我可以看到客户端的日志已被访问,但它不会去获取数据。 但是,如果在我的 LogRetrieverResource 类的循环中,我使用相同的运行方法创建一个新的 Thread 实例,则多线程数据提取将按预期工作。有人可以指出我做错了什么吗?除了实现 Runnable 接口(interface)方法之外,我之前没有在 java 中使用多线程的经验。

编辑:添加客户端类详细信息

import javax.ws.rs.client.Client;
public class CustomHttpClient {

public Response invokeExternalAPI() {
return client
    .target("url") //removing url for confidentiality
    .request()
    .accept(MediaType.APPLICATION_JSON)
    .cookie("SSO",<token>)
    .get();

}
}

最佳答案

只是想注意差异,应该不会有太大差异。首先在执行程序提交循环的末尾添加 service.shutdown()。那么你几乎会做同样的事情。

下一期,异常的处理方式略有不同。执行器服务将捕获所有异常。出于调试目的,您可以尝试。

service.submit(
    () -> {
        try{
          new LogRetrievingService (client).run();
        } catch(Exception e){
        //log the exception so you can see if anything went wrong.
        }
     }); 

但这不是使用 ExecutorService 处理异常的方法,您应该获取提交的 future 并使用它来处理任何错误。另外,我怀疑 spring 有一些工具可以完成此类工作。

关于java - ExecutorService 不起作用,但单独创建线程可以,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60599874/

相关文章:

java - 耦合和内聚示例(重构代码)

用于 cobol 显示和解压缩数字字段的 Java 映射

java - 我有一台双核机器。在java中,我的计算机如何管理3个线程的fixedThreadPool? jvm 的可能行为是什么?

java - 停止线程内的无限循环

java - 找出每个线程中 hibernate 的确切时间

用于搜索推文的 Java 代码

Java RMI - 何时创建 stub 、启动注册表并指定代码库?

java - 春+ hibernate : LocalSessionFactoryBean - NoSuchMethodError: org. hibernate.cfg.annotations.reflection.XMLContext

java - Executors.newFixedThreadPool 没有终止

c - 通过调用共享 DLL 在两个线程之间进行信息交换