2010-06-22 6 views
3

Nous développons une application Java avec plusieurs threads de travail. Ces threads devront fournir beaucoup de résultats de calcul à notre thread d'interface utilisateur. L'ordre dans lequel les résultats sont livrés n'a pas d'importance.Quelle collection prend en charge plusieurs insertions simultanées?

À l'heure actuelle, tous les threads poussent simplement leurs résultats sur une pile synchronisée - mais cela signifie que chaque thread doit attendre les autres threads avant que les résultats puissent être délivrés.

Existe-t-il une structure de données qui supporte des insertions simultanées à chaque insertion en temps constant?

Merci,

Martin

Répondre

10

ConcurrentLinkedQueue est conçu pour la haute contention. Les producteurs mettent en file d'attente des éléments à une extrémité et les consommateurs collectent des éléments à l'autre extrémité, de sorte que tout est traité dans l'ordre où il a été ajouté.

ArrayBlockingQueue est mieux pour les conflits inférieurs, avec un surdébit inférieur.

Modifier: Bien que ce n'est pas ce que vous avez demandé. Simultaneuos inserts? Vous souhaiterez peut-être donner à chaque thread une file d'attente de sortie (par exemple, un ArrayBlockingQueue), puis demander au thread d'interface d'interroger les files d'attente séparées. Cependant, je pense que vous trouverez l'une des deux implémentations Queue ci-dessus suffisante.

+0

+1: C'est certainement un cas pour les implémentations simultanées de 'Queue'. –

+0

@Andrzej: pour moi, cela ressemble plus à un cas d'optimisation prématurée. –

+0

@Michael pas vraiment - il est parfaitement normal de spécifier une insertion de temps constante sur une structure de données dans laquelle vous pourriez mettre beaucoup de données, et si vous n'utilisez pas la file d'attente concurrente de la bibliothèque, vous avez plus de code à écrire et il est plus difficile de tester afin d'obtenir quelque chose qui a le bon comportement. Il n'y a rien dans le PO ou ce post qui dit quoi que ce soit sur l'optimisation, juste l'exactitude dans les exigences. –

0

Jetez un oeil à java.util.concurrent.ConcurrentLinkedQueue, java.util.concurrent.ConcurrentHashMap ou java.util.concurrent.ConcurrentSkipListSet. Ils pourraient faire ce dont vous avez besoin. ConcurrentSkipListSet, par exemple, prétend avoir "moyen log coût de temps pour les opérations contains, add et remove et leurs variantes.Les opérations d'insertion, de suppression et d'accès s'exécutent en toute sécurité simultanément par plusieurs threads."

0

Deux autres modèles, vous voudrez peut-être regarder sont

  • chaque thread a sa propre collection, lorsque sondé il retourne la collection et crée une nouvelle, de sorte que la collection ne contient que les éléments en suspens entre les sondages . Le thread doit protéger les opérations sur sa collection, mais il n'y a pas de conflit entre les threads. Cela bloque (chaque thread ne peut pas ajouter à sa collection alors que le thread UI en tire des mises à jour), mais peut réduire la contention (pas de conflit entre les threads). Chaque thread a sa propre collection et ajoute les résultats à une file d'attente commune qui est protégée à l'aide d'un Lock.tryLock (0). Le thread poursuit le traitement s'il ne parvient pas à acquérir le verrou. Cela rend moins probable qu'un thread bloquera l'attente de la file d'attente partagée.

+0

Y at-il plus à cette réponse? –

+0

@Ben J'avais changé de mon IDE où tab + enter aurait indenté et donner une nouvelle ligne plutôt que de soumettre –

3

En ce moment, toutes les discussions pousser simplement leurs résultats sur une synchronisation Stack - mais cela signifie que chaque thread doit attendre les autres threads avant que les résultats peuvent être livrés.

Avez-vous des preuves qu'il s'agit réellement d'un problème?Si le calcul effectué par ces threads est même le plus petit complexe (et vous n'avez pas littéralement des millions de threads), alors le conflit de verrous sur la pile de résultats est simplement un non-problème car lorsqu'un thread donné délivre ses résultats, tous d'autres sont très probablement occupés à faire leurs calculs.

+0

Vous avez raison, mais comme un grand nombre de résultats sont calculés, chaque calcul étant assez rapide, je me suis dit qu'il y aurait probablement être des collisions. Aussi, je suis simplement devenu curieux de savoir si une telle collection de données existe :) –

+1

@Martin: confirmez, ne "figurez" pas. Regardez votre application dans la vue des threads de VisualVM et voyez combien de temps ils passent à attendre des verrous. Et si c'est vraiment important, pourquoi chaque thread ne fait-il pas des compilations en plus gros paquets avant de soumettre des résultats? Beaucoup réduisent aussi les frais généraux d'autres façons. –

1

Prenez un peu de recul et évaluez si la performance est la clé de la conception ici. Ne pensez pas, sachez: le profilage le soutient-il? Si ce n'est pas le cas, je dirais que la plus grande préoccupation est la clarté et la lisibilité de la conception, et non l'introduction d'un nouveau code à maintenir. Il se trouve juste que, si vous utilisez Swing, il y a une bibliothèque pour faire exactement ce que vous essayez de faire, appelé SwingWorker. +1:

Questions connexes