J'ai un scénario où
Plusieurs threads poussent des données sur une file d'attente p> li>
Un seul thread est le traitement des données à l'aide de code ci-dessous p> li> ul>
code - p> mais parfois, la file d'attente.Dequeue () renvoie null dans le scénario ci-dessus
Ce qui donne? P> p>
7 Réponses :
Assurez-vous que rien ne pousse null code> dans la file d'attente.
null code> s sont autorisés comme des valeurs en file d'attente. Aussi, selon Ce document , uniquement
Queue
Vous êtes mal compris que le document. Il disant que seuls les membres statiques i> de la file d'attente code> sont garantis pour être en sécurité. L'attribution d'une file d'attente à une variable statique ne le rend pas magiquement à fil-sûr.
Il n'y a pas de nulls étant poussé dans
Suivi sur le commentaire de Slaks: Queue
Références Code>).
Merci, @slaks et @jeff. Cela donne beaucoup plus de sens.
Vous devez synchroniser l'accès à la file d'attente. Mettez verrouillage code> sur toutes les sections de code qui accèdent à la file d'attente (lecture et écriture). Si vous accédez à la file d'attente simultanée à partir de plusieurs threads, les structures internes peuvent être corrompues et à peu près tout peut arriver. P>
Si "Accès" signifie lire, il n'y a que 1 lecteur de repos (2) sont des écrivains
@Kumar: Avoir deux écrivains (sur des threads distincts) Ajouter à une collection qui n'est pas intrinsèquement thread-coffre-fort va causer des problèmes. Le droit de Guffa; Vous devez synchroniser l'accès. Voir ma réponse pour une sorte d'explication occasionnelle.
Hmm ... Seriez-vous en mesure d'utiliser un java.util.concurrent.synchronousqueue code> au lieu des relevés de verrouillage? Je n'ai pas encore traité cette classe.
Si vous utilisez .NET 4, vous pouvez éviter de verrouiller en utilisant le type ConcurrentQueue: CODETHinked.com/post/2010/02/04/...
Notez que dans ce scénario, une serrure exclusive a du sens. Si le scénario était de nombreux lecteurs, un écrivain, au lieu de l'inverse, alors une lectureWriterLockslim serait une meilleure solution.
Vous devez lire Ce blog post .
En outre, voici un squelette très minime d'un" canal "pour la communication entre les threads: p>
Semble intéressant mais je préférerais utiliser le verrouillage de manière minimale, peut-être du temps pour enfin passer à travers la bibliothèque PowerTheading en détail
Si vous souhaitez utiliser un conteneur standard à partir de plusieurs threads, le code ci-dessus est minimal! Mais le powerTheading vaut la peine de regarder quand même.
Pourquoi ne résolvez-vous pas le problème de cette façon? OK, après avoir lu des commentaires sur les écarts et toutes les autres réponses, vous allez bien et Je suis juste faux. Donc MISE À JOUR H3>
Étant donné que la méthode code> DEQUEUE code> de la file d'attente code> n'est pas la sécurité du fil. Si un lecteur tente de le faire en même temps qu'un écrivain tente d'insérer quelque chose, les résultats seront ... imprévisibles.
Vous dites:
Les threads multiples poussent des données sur une file d'attente p> blockQuote>
La file d'attente
.NEnqueue code> n'est pas du thread-coffre-fort. Cela signifie que le travail est effectué dans strong> la méthode code> Enqueue code> qui doit être synchronisée si plusieurs threads l'appellent. Un exemple simple serait la mise à jour de la propriété compteur code>. C'est un pari sûr que quelque part dans la méthode code> Enqueue code> Il y a une ligne qui ressemble à ceci comme ceci: p>
xxx pré> mais comme nous savons tous que ce n'est pas t une opération atomique. C'est vraiment plus comme ça (en termes de ce qui est effectivement se passe em>): p>
xxx pré> alors dites que le compte
code> est actuellement 5 et thread 1 devient passé
int NewCount = comptage + 1 code> ... puis thread 1 pense: "OK, le compte est maintenant 5, donc je vais le faire 6." Mais la prochaine opération suivante qui est exécutée est l'endroit où le thread 2 devient
int NewCount = comptage + 1 code> et pense la même chose que le fil 1 ("Le comte est maintenant de 6"). Donc, deux éléments viennent d'être ajoutés à la file d'attente, mais le comte n'est allé que de 5 à 6. P>
Ceci est juste un exemple très fondamental de la manière dont une méthode non thread-sûre comme
la queue
.NEnqueue code> peut être gâché lorsque l'accès n'est pas synchronisé. Cela n'explique pas spécifiquement ce qui se passe dans votre question; Mon intention est simplement de souligner que ce que vous faites n'est pas du thread-sûr et causera un comportement inattendu fort>. p> p>
GUFFA est correct, ayant de multiples threads Lecture et écriture à la file d'attente entraînera des problèmes, car la file d'attente Si vous êtes sur .NET 4, utilisez le Concurrentqueur
Concurrentqueue
Oui, il y a un port de Microsoft. Il est à l'intérieur de la structure Rx pour .NET 3.5: MSDN.MicRosoft.com/fr- US / DEVLABS / EE794896.ASPX
Si vous utilisez une file d'attente non générique (non que je conseille de l'utiliser), vous pouvez utiliser la méthode de la file d'attente.Synchronisée pour obtenir un wrapper à fil-coffre-fort:
Queue queue = Queue.Synchronized(new Queue());