Prawidłowa implementacja wielowątkowości Java Future
W moim serwletu klikam kilka adresów URL, aby sprawdzić ich status i zwrócić odpowiedź użytkownikowi.
Uderzanie w żądania wielopłaszczyznowe zajmuje dużo czasu: potrzebujesz wątków i limitów czasu. Ale potrzebuję odpowiedzi na moje wątki: z tego powodu korzystam z Future.
Mój zarys kodu:
ExecutorService executor = Executors.newFixedThreadPool(10);
Future<statusModel> future;
for (Map.Entry<String, String> url : urls.entrySet())
{
try
{
future = executor.submit(new CallableRequestStatus(url.getValue()));
status = (statusModel) future.get(5, TimeUnit.SECONDS);
results.add(status);
}
catch (InterruptedException | ExecutionException | TimeoutException e)
{
System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());
}
}
executor.shutdownNow();
Wszystkie wyniki z mojej wywoływalnej klasy są w obiekcie statusu, który później dodaję do arraylisty. Moim problemem jest to, że moje podejście blokuje mi uruchamianie wszystkich 10 wątków jednocześnie. Muszę poczekać 5 sekund, aby uzyskać mój obiekt statusu, a następnie przejść do następnego adresu URL.
Myślę, że moje podejście jest błędne. Próbowałem szukać online, ale nie mogłem znaleźć żadnego przykładu z obiektami niestandardowymi i arraylistami.
Czy ktoś może mi pomóc naprawić moją winę? Z góry dziękuję
Wreszcie zaktualizowałem mój kod (dzięki Sotirios Delimanolis i Kevin):
ExecutorService executor = Executors.newFixedThreadPool(20);
List<Future<statusModel>> futures = new ArrayList<Future<statusModel>>();
for (Map.Entry<String, String> url : urls.entrySet())
{
Future<statusModel> future = executor.submit(new CallableRequestStatus(url.getValue()));
futures.add(future);
}
ArrayList<statusModel> results = new ArrayList<statusModel>();
statusModel status;
int i=0;
for (Map.Entry<String, String> url : urls.entrySet())
{
try
{
status = (statusModel) futures.get(i).get(500, TimeUnit.MILLISECONDS);
// do some stuff with status and
if(status.getStatusCode()/100 == 2)
results.add(status);
}
catch (InterruptedException | ExecutionException | TimeoutException e)
{
System.out.println("Error<checkServers>: Timeout OR "+e.getMessage());
}
i++;
}
executor.shutdownNow();
System.out.println("Shutdown: "+executor.isShutdown());
Miej nadzieję, że to dla kogoś pomocne :)