J'utilise ExecutorService pour faciliter le programme multithread concurrent. Prenez le code suivant:ExecutorService, moyen standard pour éviter que la file d'attente des tâches ne soit trop pleine
while(xxx)
ExecutorService exService = Executors.newFixedThreadPool(NUMBER_THREADS);
...
Future<..> ... = exService.submit(..);
...
}
Dans mon cas, le problème est que submit() ne bloque pas si tous les NUMBER_THREADS sont occupés. La conséquence est que la file d'attente des tâches est inondée par de nombreuses tâches. La conséquence de ceci est que l'arrêt du service d'exécution avec ExecutorService.shutdown() prend des âges (ExecutorService.isTerminated() sera faux pendant longtemps). Raison est que la file d'attente de tâches est encore assez complète.
Pour l'instant ma solution de contournement est de travailler avec des sémaphores pour désavouer avoir à plusieurs entrées dans la file d'attente des tâches de ExecutorService:
...
Semaphore semaphore=new Semaphore(NUMBER_THREADS);
while(xxx)
ExecutorService exService = Executors.newFixedThreadPool(NUMBER_THREADS);
...
semaphore.aquire();
// internally the task calls a finish callback, which invokes semaphore.release()
// -> now another task is added to queue
Future<..> ... = exService.submit(..);
...
}
Je suis sûr qu'il ya une meilleure solution plus encapsulées?
je vois. J'ai négligé un détail à http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29. là, il est mentionné, qu'en standard une file d'attente illimitée est utilisée. –
je l'ai essayé. Malheureusement, votre solution ne bloque pas (comme je le veux) mais lance une exception RejectedExecutionException. également trouvé: http://www.velocityreviews.com/forums/t389526-threadpoolexecutor-with-blocking-execute.html. les solutions de contournement présentées semblent être plus compliquées que mon exemple de sémaphore, putain! –
cela ne fonctionne pas à cause de RejectedExecutionException si la file d'attente est pleine – user249654