[JAVA] Ist drainTo von LinkedBlockingQueue sicher? Ich bin der Quelle gefolgt

Überblick

Ich habe mich für "drainTo" entschieden, weil ich den Status des temporären Punkts von "LinkedBlockingQueue" in meinem Unternehmen abrufen musste.

drainTo ist

Entfernt alle verfügbaren Elemente aus dieser Warteschlange und fügt sie der angegebenen Sammlung hinzu.

Es ist eine Methode namens.

Wenn Sie sich jedoch die Hilfe ansehen,

Das Verhalten dieser Operation ist undefiniert, wenn die angegebene Auflistung während der Operation geändert wird.

Publisher

Es gab einen unangenehmen Satz, und ich untersuchte, ob es ein Problem gab.

30.11.2017 Nachtrag

Quelle

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();
    }
}

Darüber hinaus wird tatsächlich "drainTo" mit einem Argument verwendet:

LinkedBlockingQueue.java


return drainTo(c, Integer.MAX_VALUE);

Und da nur dieselbe Methode aufgerufen wird, die überladen ist, gibt es kein Problem, wenn Sie dies überprüfen.

Variable

takeLock Ein Sperrobjekt zum Sperren des ** Abrufs ** von Daten.

putLock Obwohl es in der obigen Quelle nicht angezeigt wird, ist es ein Sperrobjekt zum Sperren des ** Hinzufügens ** von Daten.

count Ein Feld vom Typ "AtomicInteger". Jedes Mal, wenn ich die Daten ändere, scheint es, dass ich sie in der Klasse manuell ändere. (Es scheint, dass es nicht nur "Queue.size" zurückgibt)

Kommentar

Wir werden nur die notwendigen Teile in der Reihenfolge von oben betrachten.

final ReentrantLock takeLock = this.takeLock;
takeLock.lock();

Erwerben Sie die Erfassungssperre, bevor Sie mit der Datenerfassung beginnen.

int n = Math.min(maxElements, count.get());

Bevor Sie mit der Datenerfassung beginnen, ** entscheiden Sie, wie viele Elemente von Anfang an erfasst werden sollen **. Auf diese Weise können Sie ** die während des DrainTo-Prozesses ** hinzugefügten Daten ignorieren.

Fazit

Es scheint, dass es gesagt werden kann.

Nebenbei (Eindruck)

persönlich,

** Wenn Sie alle Daten auf einmal erhalten möchten, sollten Sie die Ergänzungen in der Zwischenzeit sperren! ** ** **

Ich werde denken.

Ich fragte mich, ob es einen Ansatz gab, "zuerst die Anzahl der Daten zu bestimmen". Es war eine sehr gute Studie.

Recommended Posts

Ist drainTo von LinkedBlockingQueue sicher? Ich bin der Quelle gefolgt
Ich habe die Quelle von ArrayList gelesen, die ich gelesen habe
Ich habe die Quelle von Integer gelesen
Ich habe die Quelle von Long gelesen
Ich habe die Quelle von Short gelesen
Ich habe die Quelle von Byte gelesen
Ich habe die Quelle von String gelesen
05. Ich habe versucht, die Quelle von Spring Boot zu löschen
'% 02d' Was ist der% von% 2?
[Referenzbeispiel] Das Urheberrecht wird im Kommentar des Quellcodes beschrieben.
Was ist ein Test? ・ Über die Wichtigkeit eines Tests
Ich habe die interne Verarbeitung von Retrofit untersucht
[Tag: 5] Ich habe die Grundlagen von Java zusammengefasst
Wie ist die Datenstruktur von ActionText?
Was ist JSP? ~ Lassen Sie uns die Grundlagen von JSP kennen !! ~
Der ActiveSupport-Unterstrich ist nicht die inverse Konvertierung von camelize
Ich habe den Teil von java.net.URL # getPath überprüft
Die Reihenfolge der Java-Methodenmodifikatoren ist festgelegt
Ich habe die Grundlagen der Zeicheneingabe verstanden
Ich habe die Eigenschaften von Java und .NET verglichen
Ich möchte den Inhalt der Absicht var_dump
Der offizielle Name von Spring MVC ist Spring Web MVC
Ich habe versucht, den Profiler von IntelliJ IDEA zu verwenden
Ich habe die Anzahl der Taxis mit Ruby überprüft
Probieren Sie Progate Free Edition [Java I]
Der Umgang mit Java Future ist zu langweilig, daher werde ich verschiedene Ideen ausprobieren.