Eigentlich ist das ja schon durch, aber nochmal meine 2 cents:
Ich nehme an, dass mit „concurrent container“ entweder…
- (unwahrscheinlich: ) irgendeine Collection gemeint war, die von mehreren Threads verwendet wird, oder
- irgendeine der Collections aus dem
java.util.concurrent
package
Ersteres ist unwahrschenlich. Das kracht praktisch zwangsläufig früher oder später irgendwo. Aber auch die Container/Collections aus java.util.concurrent
sind nur „thread safe“ in dem Sinne, dass es nicht „kracht“. Ob der Zustand, den man sieht, in irgendeinem Sinne „konsistent“ ist (speziell in dem Sinne, ob der beobachtete Zustand den (unfundierten und aus Wunschdenken resultierenden ) Erwartungen des Programmierers entspricht), ist eine komplett andere Frage.
Darüber hinaus: Die Unterscheidung zwischen „zukünftige und aktuelle Größe“ macht tatsächlich nicht viel Sinn. Jede Unterhaltung darüber würde es erfordern, dass man weeeeit ausholt und über das Java Memory Model, „Happens Before“ und das Konzept von Zeit an sich redet.
Die Quintessenz ist:
In der skizzierten Abfrage könnte es sein, dass isEmpty()
ein true
liefert, aber size() == 0
dann false
ist, weil zwischendrin ein anderer Thread etwas in den Container gepackt hat. (Durch reines Iterieren, wie in der Frage geschrieben, ändert sich da natürlich nichts, aber ich nehme an, dass es um den Fall ging, wo ein anderer Thread Elemente hinzufügt oder entfernt).
Und das kann auch sein, obwohl die Standard-Implementierung von isEmpty
in AbstractCollection
so aussieht:
/**
* {@inheritDoc}
*
* <p>This implementation returns <tt>size() == 0</tt>.
*/
public boolean isEmpty() {
return size() == 0;
}
(Gerade bei … „ausgefeilteren“ Collections, wie ConcurrentLinkedQueue
oder so, kann die Implementierung anders sein, aber das ist hier nicht soooo relevant…)
Ohne irgendeine Form von Synchronisation sind die beiden Aufrufe in der if
-Abfrage komplett getrennte Dinge, zwischen denen (theoretisch) einige Minuten liegen können, in denen ein anderer Thread die Collection befüllt, drüberiteriert, nochmal leert, wieder füllt,… und damit am Ende „irgendein“ Ergebnis bei der if
-Abfrage rauskommt.