2010-07-29 4 views
1

J'ai une procédure (procA) qui doit appeler plusieurs fois un webservice et retourner l'ensemble des résultats.opération multithread limitée

procA peut être appelée une poignée de fois simultanément.

Les appels vers le service Web prennent un certain temps, mais les appels simultanés n'ont pas d'impact important sur les performances.

Il serait donc avantageux de créer un pool de threads pour que procA fasse les appels au webservice de sorte qu'un seul appel à procA puisse faire tous ses appels vers le webservice et attendre qu'ils soient tous terminés avant de continuer .

Cependant je ne veux pas avoir un pool de threads par procA car s'il y a plusieurs appels simultanés à procA, je veux limiter/étrangler le nombre total de threads accédant au webservice à la fois.

la solution optimale serait un pool de threads partagé que chaque appel aux partages procA. Le seul problème que j'ai besoin d'aide pour résoudre est comment puis-je dire que toutes les tâches de service Web en file d'attente par le premier appel à procA sont terminées?

EDIT: pile trace

Daemon Thread [http-80-4] (Suspended) 
    Unsafe.park(boolean, long) line: not available [native method] 
    LockSupport.park(Object) line: 158 
    FutureTask$Sync(AbstractQueuedSynchronizer).parkAndCheckInterrupt() line: 747 
    FutureTask$Sync(AbstractQueuedSynchronizer).doAcquireSharedInterruptibly(int) line: 905 
    FutureTask$Sync(AbstractQueuedSynchronizer).acquireSharedInterruptibly(int) line: 1217 
    FutureTask$Sync.innerGet() line: 218  
    FutureTask<V>.get() line: 83  
    ThreadPoolExecutor(AbstractExecutorService).invokeAll(Collection<Callable<T>>) line: 205  
    ... 

Répondre

4

La chose la plus facile est d'utiliser un bon ExecutorService et il suffit d'utiliser la méthode invokeAll. Vos travaux s'exécutent de manière asynchrone et la méthode d'appel est bloquée jusqu'à ce que tous soient terminés.

Alternativement, vous pourriez avoir chaque instance de procA rassembler une collection des objets Future qui vont avec le travail soumis à l'exécuteur. (Ou faites-le dans la portée de la méthode, le cas échéant.) Puis passez en revue sur eux et bloquer sur leurs méthodes get(). Lorsque la boucle est terminée, le travail est terminé.

+0

pas mal, je vais l'essayer! – pstanton

+0

re modifier, événement mieux! donnera la tique une fois que j'ai testé. – pstanton

+0

cela fonctionne, mais il semble être coincé à invokeAll de temps en temps, voir mon edit pour une pile trace du fil .. – pstanton