BlockingQueue a la méthode appelée drainTo() mais n'est pas bloquée. J'ai besoin d'une file d'attente que je veux bloquer mais aussi capable de récupérer des objets en file d'attente dans une seule méthode. Je suppose que le code ci-dessus va fonctionner, mais je suis à la recherche d'une solution élégante.BlockingQueue - méthodes drainTo() bloquées
Répondre
Vous parlez de commentaire dans le JavaDoc:
De plus, le comportement de cette opération est définie si la collection spécifiée est modifiée pendant que l'opération est en cours.
Je crois que cela fait référence à la collection list
dans votre exemple:
blockingQueue.drainTo(list);
qui signifie que vous ne pouvez pas modifier list
en même temps que vous drainent de blockingQueue
en list
. Cependant, la file d'attente de blocage se synchronise de manière interne de sorte que lorsque drainTo
est appelée,
puts et
(voir la remarque ci-dessous) seront bloqués. Si ce n'était pas le cas, cela ne serait pas vraiment sans danger pour les threads. Vous pouvez regarder le code source et vérifier que drainTo
est thread-safe concernant la file d'attente de blocage elle-même.
Alternativement, voulez-vous dire que lorsque vous appelez drainTo
que vous voulez qu'il bloque jusqu'à ce qu'au moins un objet a été ajouté à la file d'attente? Dans ce cas, vous avez peu d'autre choix que:
list.add(blockingQueue.take());
blockingQueue.drainTo(list);
pour bloquer jusqu'à ce qu'un ou plusieurs éléments ont été ajoutés, puis égoutter toute la file d'attente dans la collection list
.
Remarque: Depuis Java 7, un verrou séparé est utilisé pour les transactions get et puts. Les opérations de Put sont maintenant permises pendant un drainTo (et un certain nombre d'autres opérations de prise).
Avec l'API disponible, je ne pense pas que vous allez devenir beaucoup plus élégant. Autre que vous pouvez supprimer le test de taille.
Si vous souhaitez extraire de manière atomique une séquence contiguë d'éléments même si une autre opération de suppression coïncide, je ne crois pas que drainTo
le garantisse.
drainPermet définitivement de bloquer tout put, get, take, etc ... Vérifiez le code source. Cette API est thread-safe contre d'autres appels à la file d'attente de blocage. Cependant, si la collection à laquelle vous vidange change pendant drainTo, vous pouvez avoir un problème. – Eddie
Vérifiez le code source? C'est une interface! –
OK, vrai, drôle, mais à part le point. Vérifiez les classes d'implémentation dans le JDK. (Ce qui est clairement ce que je voulais dire.) – Eddie
code source:
596: public int drainTo(Collection<? super E> c) {
//arg. check
603: lock.lock();
604: try {
608: for (n = 0 ; n != count ; n++) {
609: c.add(items[n]);
613: }
614: if (n > 0) {
618: notFull.signalAll();
619: }
620: return n;
621: } finally {
622: lock.unlock();
623: }
624: }
ArrayBlockingQueue est impatient de retourner 0. BTW, il pourrait le faire avant de prendre le verrou.
Non. Prendre le verrou ne permet pas seulement une exclusion mutuelle, il s'assure également que le compte vu est "frais", que les mises à jour de la mémoire principale provenant d'autres threads sont visibles. Vous pouvez rendre le compte "volatile", mais les écritures volatiles sont relativement lentes, donc l'écriture signifierait à la fois le verrouillage et l'écriture volatile, probablement plus de frais généraux. À mon humble avis tout développeur développeur code concurrent devrait tenter de faire de son mieux pour comprendre le modèle de mémoire de Java: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4 –
J'ai trouvé ce modèle utile.
List<byte[]> blobs = new ArrayList<byte[]>();
if (queue.drainTo(blobs, batch) == 0) {
blobs.add(queue.take());
}
Si vous arrive d'utiliser Google goyave, il y a une méthode astucieuse Queues.drain()
.
Drains la file d'attente comme
BlockingQueue.drainTo(Collection, int)
, mais si les demandéesnumElements
éléments ne sont pas disponibles, il attendra les jusqu'à le délai spécifié.
C'est exactement ce dont j'avais besoin, merci. – Alan
- 1. Deux BlockingQueue - impasse
- 2. Java BlockingQueue de taille = 1?
- 3. Entrées de registre bloquées Prévention de désinstallation
- 4. Équivalent Objective-C de BlockingQueue de Java?
- 5. Plusieurs requêtes HTTP complètes bloquées dans l'état TCP CLOSE_WAIT
- 6. BlockingQueue: put() et isEmpty() ne fonctionnent pas ensemble?
- 7. Lors du téléchargement d'un fichier, toutes les demandes sont bloquées
- 8. Comment afficher autre chose si les annonces Google sont bloquées?
- 9. Transformation de méthodes C# en méthodes C++
- 10. Pourquoi nos requêtes sont-elles bloquées sur l'état "Ecrire sur le net" dans MySQL?
- 11. Meilleure méthode pour obtenir des objets à partir d'un BlockingQueue dans un programme concurrent?
- 12. Méthodes AutoRun
- 13. méthodes autorun
- 14. Méthodes Linq
- 15. Méthodes d'instance appelant des méthodes de classe appelant des méthodes d'instance
- 16. Méthodes de simulation utilisées dans les méthodes statiques
- 17. Noms de méthodes pour les méthodes d'opérateur en C#
- 18. Méthodes d'ordonnancement pthread?
- 19. jQuery plugin méthodes personnalisées
- 20. Django Models méthodes internes
- 21. Java: `Méthodes static`
- 22. VB.NET Extension Méthodes
- 23. pointeur pointeur C++ Méthodes
- 24. Regroupement des méthodes javadoc
- 25. F # Méthodes statiques multilignes
- 26. Méthodes et délégués anonymes
- 27. Référencement Méthodes AppDelegate - iphone
- 28. décorateurs et méthodes python
- 29. Outils et méthodes
- 30. Surcharge des méthodes
Il est peu probable que la collection à laquelle vous copiez soit thread-safe. Quel serait le but? –
Est-il garanti que drainTo (list) n'appellera pas list.clear()? Je ne vois pas ça dans le javadoc n'importe où. – Recurse
@Recurse: Le JavaDoc ne * garantit * pas que drainTo (list) n'appellera pas clear(), je suppose, car il ne dit pas qu'il ne le fera pas. Cependant, il serait très surprenant que l'on fasse quelque chose de si important à une collection sans documenter cette action. Beaucoup considéreraient ceci comme un bug sérieux. – Eddie