Dans mon servlet, je tape plusieurs URL pour vérifier leur statut et retourner la réponse à l'utilisateur.Mise en œuvre correcte de Java Future multithread
Frapper des requêtes multipaires prend beaucoup de temps: besoin de threads et de timings. Mais j'ai besoin de mes threads pour obtenir la réponse: utiliser Future pour cette raison.
Mon plan de code:
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();
Tous les résultats de ma classe appelable est à venir dans l'objet d'état que j'ajouter plus tard à un ArrayList. Mon problème ici est que mon approche me bloque d'exécuter tous les 10 threads en même temps. Je dois attendre 5 secondes pour obtenir mon objet d'état, puis passer à l'URL suivante.
Je pense que mon approche est défectueuse. J'ai essayé de regarder en ligne mais je ne pourrais trouver aucun exemple avec des objets faits sur commande et Arraylist impliqué.
Quelqu'un peut-il m'aider à corriger ma faute. Merci à l'avance
enfin mis à jour mon code (grâce à Sotirios Delimanolis et 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());
Espoir pour quelqu'un son utile :)
Ajoutez tous les contrats à terme à un ensemble ou à une liste. Après avoir soumis tous vos callables, parcourez les éléments 'Future' et appelez' get' sans valeur de délai. Votre thread principal bloquera, mais les autres tâches continueront à s'exécuter. Vous attendez essentiellement la durée du callable le plus long. –
Merci Sotirios pour une réponse rapide. J'ai essayé ce que vous avez suggéré mais je suis toujours bloqué quand je boucle sur futureList pour les serveurs qui prennent trop de temps. –
Si vous devez attendre que tous les serveurs répondent et obtiennent tous leurs résultats, c'est la seule manière synchrone de le faire. –