J'ai décidé d'utiliser drainTo
car mon entreprise avait besoin d'obtenir le statut du point temporaire de LinkedBlockingQueue
.
drainTo
est
Supprime tous les éléments disponibles de cette file d'attente et les ajoute à la collection spécifiée.
C'est une méthode appelée.
Cependant, si vous regardez l'aide,
Le comportement de cette opération n'est pas défini si la collection spécifiée est modifiée pendant que l'opération est en cours.
Il y a eu une peine difficile et j'ai vérifié s'il y avait un problème.
PostScript 30/11/2017
LinkedBlockingQueue.java
/**
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
*/
public int drainTo(Collection<? super E> c, int maxElements) {
if (c == null)
throw new NullPointerException();
if (c == this)
throw new IllegalArgumentException();
if (maxElements <= 0)
return 0;
boolean signalNotFull = false;
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
int n = Math.min(maxElements, count.get());
// count.get provides visibility to first n Nodes
Node<E> h = head;
int i = 0;
try {
while (i < n) {
Node<E> p = h.next;
c.add(p.item);
p.item = null;
h.next = h;
h = p;
++i;
}
return n;
} finally {
// Restore invariants even if c.add() threw
if (i > 0) {
// assert h.item == null;
head = h;
signalNotFull = (count.getAndAdd(-i) == capacity);
}
}
} finally {
takeLock.unlock();
if (signalNotFull)
signalNotFull();
}
}
De plus, ce qui est réellement utilisé est drainTo
avec un argument,
LinkedBlockingQueue.java
return drainTo(c, Integer.MAX_VALUE);
Et, comme il appelle simplement la même méthode qui est surchargée, il n'y a pas de problème si vous cochez ici.
takeLock Un objet de verrouillage pour verrouiller la ** récupération ** des données.
putLock Bien qu'il n'apparaisse pas dans la source ci-dessus, il s'agit d'un objet de verrouillage permettant de verrouiller ** l'ajout ** de données.
count
Champ de type ʻAtomicInteger. Chaque fois que je change les données, il semble que je les change manuellement dans la classe. (Il semble qu'il ne s'agit pas simplement de renvoyer
Queue.size`)
Nous examinerons uniquement les pièces nécessaires dans l'ordre du haut.
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
Acquérir le verrouillage d'acquisition avant de lancer l'acquisition de données.
Avez-vous besoin d'un verrou supplémentaire? * J'ai pensé, mais ce n'est plus nécessaire en raison du traitement suivant.
Obtenez le numéro
int n = Math.min(maxElements, count.get());
Avant de commencer l'acquisition de données, ** décidez du nombre d'articles à acquérir dès le début **. En faisant cela, vous pouvez ** ignorer les données ajoutées pendant le processus de drainTo **.
drainTo
.drainTo
car le nombre de données acquises est calculé en premier.LinkedBlockingQueue.drainTo
peut être exécuté en toute sécurité même dans un environnement multithread.Il semble que cela puisse être dit.
personnellement,
** Si vous souhaitez obtenir toutes les données en même temps, vous devez verrouiller les ajouts en attendant! ** **
Je penserai.
Je me suis demandé s'il existait une approche consistant à «décider d'abord du nombre de données». C'était une très bonne étude.
Recommended Posts