簡體   English   中英

Java 並發執行器服務返回不一致的響應

[英]Java Concurrent Executor Service returning inconsistent responses

這里我配置了一個調度器,它會在應用啟動后觸發function。 在調度程序中,WHILE 循環應該無限迭代並捕獲響應,直到遇到錯誤。

應用程序入口點

@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(...);
        }
    }
}

}

邏輯

@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 一旦調度器啟動:-

第一次迭代響應: [E, A, D, C, B]

第二次迭代響應: [A, D, E]

第三次迭代響應: [A, C, D, E]

第 4 次迭代響應: [A, B, C, D, E]

很快....

為什么響應大小不一致?

在所有迭代中,我希望大小相同,即 5。我的理解是, future.get(...)將阻塞代碼流,直到任務執行完成。

多個線程正在寫入相同的響應,使用線程安全寫入,您可以使用CopyOnWriteArrayList代替:

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

調用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