简体   繁体   English

Java 并发执行器服务返回不一致的响应

[英]Java Concurrent Executor Service returning inconsistent responses

Here, I have configured a scheduler, which will trigger the function after the application startup.这里我配置了一个调度器,它会在应用启动后触发function。 Within the scheduler, the WHILE loop is supposed to iterate infinitely and capture responses until encountered an error.在调度程序中,WHILE 循环应该无限迭代并捕获响应,直到遇到错误。

Application Entry Point应用程序入口点

@Service
public class Application {

@Autowired
MyService service;

@Scheduled(initialDelay = 1000, fixedDelay = 30000)
public void init() {

    while (true) {
        try {
            String[] alphabets = {"a","b","c","d","e"};
            List < String > response = service.getResult(Arrays.asList(alphabets));

            system.out.println(response);

        } catch (CustomExceptionMan e) {
            throw new CustomException(...);
        }
    }
}

}

Logic逻辑

@Service
public class MyService {

public List < String > getResult(List < String > alphabets) {

    List < String > response = new ArrayList < > ();

    ExecutorService executor = Executors.newFixedThreadPool(10);
    List < Future << ? >> futures = new ArrayList < > ();

    alphabets.forEach(alpha - > {
        futures.add(executor.submit(new Runnable() {

            @Override
            public void run() {
                try {
                    apiCall(alpha, response);

                } catch (Exception e) {
                    throw new CustomException(...);
                }
            }

        }));
    });

    executor.shutdown();

    futures.forEach(i - > {
        try {
            i.get(10000, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            throw new CustomException(....);
        }
    });

    // Even Tried this
    while (!executor.isTerminated()) {}

    return response;

}

public void apiCall(String alpha, List < String > response) {
    try {
        Thread.sleep(4000);
    } catch (InterruptedException e) {}

    response.add(alpha.toUpperCase());
}
}

Output once the scheduler start:- Output 一旦调度器启动:-

1st iteration response: [E, A, D, C, B]第一次迭代响应: [E, A, D, C, B]

2nd iteration response: [A, D, E]第二次迭代响应: [A, D, E]

3rd iteration response: [A, C, D, E]第三次迭代响应: [A, C, D, E]

4th iteration response: [A, B, C, D, E]第 4 次迭代响应: [A, B, C, D, E]

so on....很快....

Why isn't the response size consistent?为什么响应大小不一致?

In all iterations, I expect the size to be same ie 5. My understanding is, future.get(...) will block the code flow until the task execution is completed.在所有迭代中,我希望大小相同,即 5。我的理解是, future.get(...)将阻塞代码流,直到任务执行完成。

Multiple threads are writing to same response, use thread-safe writes, you could use CopyOnWriteArrayList instead:多个线程正在写入相同的响应,使用线程安全写入,您可以使用CopyOnWriteArrayList代替:

List < String > response = new CopyOnWriteArrayList<>();

Calling Future.get(long timeout, TimeUnit unit) may not leave enough time for all tasks is complete, try using Future.get() instead or use ExecutorService.awaitTermination(long timeout, TimeUnit unit) on a executor service at the end rather than relying on while loop to see if tasks are ended.调用Future.get(long timeout, TimeUnit unit)可能没有足够的时间来完成所有任务,请尝试使用Future.get()代替,或者最后在执行程序服务上使用ExecutorService.awaitTermination(long timeout, TimeUnit unit)而不是而不是依靠while循环来查看任务是否结束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM