Java Thread Pools / Executor Service et wait () s - que deviennent les threads & amp; file d'attente de tâches?
J'ai regardé mais n'ai pas trouvé de réponse donc je voulais confirmer ce pour certains.
Dire que j'ai un fixe la taille du pool de threads - ExecutorService pool = Executors.newFixedThreadPool(5);
Et j'ai un code:
pool.execute(new Runnable(){
try{
Object waitForMe = doSomethingAndGetObjectToWaitFor();
waitForMe.wait();
doSomethingElse();
}catch(Exception e){ throw new RunTimeException(e) }
});
Permet de supposer que le code ci-dessus est appelé quelques fois 100. Il y a seulement 5 threads du pool (alors que 5 des déclarations ci-dessus devrait être actif à un moment). Supposons également que la wait()
est sur un objet à faire quelques appels d'e/S à une tierce partie et d'attendre un rappel lorsque l'opération est terminée donc, naturellement, il faudra un certain temps pour terminer.
Maintenant, ma question est quel est le comportement lors de l'une de ces tâches atteint un wait()
ne la tâche d'aller dormir, puis le fil de la piscine prend une autre tâche de la file d'attente et commence à courir?
Si la tâche est en attente de mise en veille ce qui se passe quand il fait un notify()
et se réveille? Le fil de retourner dans la file d'attente (à l'avant ou à l'arrière) pour le pool de threads et d'attendre jusqu'à ce que l'un des 5 threads peuvent continuer à exécuter (c'est à dire appel doSomethingelse()
)? Ou ne le thread exécutant également aller dormir dans un des 5 exécuteur fils est assis à attendre avec la tâche (c'est ce que je suppose)? Ou l'exécuteur fil ramasser une autre tâche et simplement être interrompue lorsque la première tâche est de retour de l'wait()?
source d'informationauteur NightWolf
Vous devez vous connecter pour publier un commentaire.
wait()
est une opération de blocage:Cela signifie que le fil dans la piscine va attendre, mais de l'extérieur il ressemble à la tâche en cours prend tellement de temps pour terminer. Cela signifie également que si 5 les tâches sont exécutées et ils ont tous
wait()
leExecutor
ne peut pas gérer les tâches restantes, ekhem, attendre dans la file d'attente.Vrai, l'exécuteur fil lui-même va dormir, permettant à d'autres threads de basculer et de consommer du CPU (donc vous pouvez avoir des centaines de threads en attente en même temps et que votre système est toujours réactive) mais toujours le thread est "inutilisable" et bloqué.
Une autre caractéristique intéressante est interrompre - si le thread attend quelque chose ou dort, vous pouvez l'interrompre. Notez que les deux
wait()
etThread.sleep()
déclarerInterruptedException
. AvecExecutorService
vous pouvez prendre avantage de cela en appelant simplement:avenir.annuler()
(future
est l'objet que vous avez reçu en retour lorsque soumettre tâche àExecutorService
).Enfin je pense que vous devriez revoir la conception de votre solution. Au lieu de activement d'attente pour un système externe pour terminer, fournir une API avec les rappels:
De cette façon, le système externe de l'API tout simplement vous aviser lorsque les résultats sont prêts et que vous n'avez pas à attendre et de bloquer
ExecutorService
. Enfin, sidoSomethingElse()
prend beaucoup de temps, vous pourriez même décider de le programmer ainsi, plutôt que de l'aide de tiers externe I/O fil:Mise à JOUR: vous vous demandez quoi faire au sujet des délais d'attente? Voici mon idée:
Je suppose que vous pouvez mettre en œuvre délai d'attente de la troisième partie côté et si le délai d'attente se produit, il vous suffit d'appeler
timeout()
méthode.La
wait()
ne savez rien à propos de la bande de roulement de la piscine. Et le pool de threads ne savez rien à propos de lawait()
. Donc ils ne peuvent pas interagir de toute façon.Ils fonctionnent comme à l'habitude la
wait()
juste est une longue opération de blocage, le pool de threads est juste une file d'attente de runnables à exécuter sur un nombre limité de pool de threads.J'avais commentaire sur Tomasz la réponse, mais ma réputation ne le permet pas (encore), désolé.
Je sais que la question est ancienne, mais pour les gens qui continuent à la lecture de cette page, avoir un regard sur l'Avenir et surtout de goyave est ListenableFuture qui vous permet d'enregistrer des rappels et de la chaîne de l'avenir, précisément, le but de ne pas bloquer votre thread (et donc gratuit le fil de retour à la piscine pour quelque chose d'autre pour l'utiliser).
Tous les 5 threads seront bloqués et l'application sera de l'onu-productif de l'état.
Ajoutant à
Tomasz
réponse, je tiens à mettre en œuvre mécanisme comme suit.En dehors de
TimeoutException
vous pouvez annuler l'Avenir au cours deInterruptedException & ExecutionException
. Si vous utilisez submit() au lieu de la méthode execute(),InterruptedException & ExecutionException
sera engloutie dans le cadre lui-même.