6
votes

Suspendre le consommateur en producteur / modèle de consommation

J'ai un producteur et un consommateur connecté avec blockingqueue .

Les enregistrements d'attente consommateurs de la file d'attente et le processus: xxx

J'ai besoin de mettre en pause cette processus pendant un certain temps d'un autre fil. Comment la mettre en œuvre?

Maintenant, je pense que le mettre en œuvre telle, mais cela ressemble à une mauvaise solution: xxx


1 commentaires

N'oubliez-vous pas de fournir un peu plus de contexte sur votre besoin spécifique? La raison pour laquelle je demande est que si je dois vraiment mettre en pause quelqu'un dans la chaîne, je préférerais beaucoup mettre en pause le producteur plutôt que le consommateur. Il réalise essentiellement un effet similaire sans que la file d'attente augmente à la capacité alors que la pause est en vigueur.


3 Réponses :


2
votes

Vous pouvez utiliser java.util.concurrent.lock.condiction Java Docs Pour faire une pause pendant un moment basé sur la même condition.

C'est une approche qui me semble propre et Le mécanisme ReentrantLock a un meilleur débit que synchronisé . Lisez ci-dessous l'extrait de article IBM

En tant que bonus, la mise en œuvre de RetrantLock est beaucoup plus évolutive sous contrainte que la mise en œuvre actuelle de synchronisée. (Ce est probable qu'il y aura des améliorations à la performance soutenue de synchronisée dans une future version de la JVM.) cela signifie que lorsque de nombreux threads sont tous des soumissions pour le même verrou, le total le débit va généralement être meilleur avec reentrantlock que avec synchronisé.


BlockingQingQueue est mieux connu pour la solution de problème de producteur-consommateur, et utilise également la condition pour l'attente.

Voir l'exemple ci-dessous pris de Java Doc's condition , qui est un exemple de mise en œuvre du producteur - modèle de consommation. xxx


lecture supplémentaire:


9 commentaires

Monsieur Down Downvoter, pouvez-vous prendre la douleur pour expliquer votre vote sur votre baisse s'il vous plaît?


L'homme que je déteste les bowvotes quand la personne prend un certain temps pour fournir une explication perspicace. Si cette solution ne fonctionne pas pour vous, bien. Mais cela ne mérite pas un bowvote. +1 Pour moi, même si je trouve le premier plus simple, la seconde offre une perspicacité sur les threads et la concurrence.


Pas mon bowvote, mais donner un jugement de performance basé sur un article de plus de 10 ans et plus semble-t-il sife.


@Patb merci PAL pour le stand et le support.


@Nathanhughes J'accepterais votre commentaire, j'ai essayé d'obtenir une dernière référence mais n'a pas pu trouver dans ma recherche rapide. Mais je pense que cela tiendra vrai parce que c'est le même mécanisme utilisé dans les implémentations de blocageQueue telles que ArrayBlockingQueue , linkedblockingQueue


compris, essayant juste de penser comme le Downvoter ici. pourrait aider à ajouter quelque chose comme celui-ci à la réponse?


@Nathanhughes basé sur votre commentaire, j'ai ajouté une note pour bloquer les files d'attente pour donner une confiance en OP de quelque chose de plus jamais.


Je ne baisse pas cette réponse. Mais je ne comprends pas comment appliquer reentrantlock à ma question. Plus précisément, j'ai essayé de le faire, mais a rencontré des problèmes. Si je comprends bien, je n'ai pas besoin d'utiliser des conditions. Je dois utiliser le verrouillage / déverrouiller uniquement. Mais pourquoi le fil accrocher dans la méthode déverrouille?


Quels problèmes vous courez dans? Vous n'avez aucune condition ni relation entre les consommateurs et les producteurs comme celui de l'exemple? " Mais pourquoi le fil est suspendu dans la méthode Déverrouiller? " Je ne l'ai pas compris, vous voulez dire dans votre question?



2
votes

Je pense que votre solution est simple et élégante et pense que vous devriez le garder avec quelques modifications. Les modifications que je propose sont Synchronisation .

sans elle, Les erreurs de consistance des interférences de fil et de la mémoire peuvent se produire (et très souvent) se produisent. En plus de cela, vous ne pouvez pas attendre ou notify sur un verrou que vous ne possédez pas (et que vous le possédiez si vous l'avez à l'intérieur d'un synchronisé < / code> bloc ..). Le correctif est facile, il suffit d'ajouter un Mlock synchroniser le bloc où vous attendez / en informer dessus. De plus, comme vous changez imitionné à partir d'un fil différent, vous souhaitez la marquer volatile . xxx


2 commentaires

J'ai écrit le même code. Mais ensuite, je pensais que si vous partez en bloc de synchronisation avec l'attente, je ne dois pas entrer en bloc de synchronisation avec notify. Mais j'avais tort: ​​ Stackoverflow.com/questions/13249835/...


Peut-être sera mieux remplacé si (imitionné) pendant (imitionné). Stackoverflow.com/a/2779565/1173794



1
votes

Créer une nouvelle classe qui étend une implémentation de blocingQueue . Ajoutez deux nouvelles méthodes pause () et imprévues () . Si nécessaire, considérez le drapeau pause et utilisez l'autre blockingqueue2 pour attendre (dans mon exemple uniquement dans la méthode prise () et non mettre () ): xxx


0 commentaires