Eine thread-sichere Sammlung im Vergleich zu einer nicht thread-sicheren Sammlung kann auf andere Weise betrachtet werden.
Stellen Sie sich ein Geschäft ohne Angestellten vor, außer an der Kasse. Sie haben eine Menge Probleme, wenn die Leute nicht verantwortungsbewusst handeln. Nehmen wir zum Beispiel an, ein Kunde nimmt eine Dose aus einer Pyramidendose, während ein Angestellter gerade die Pyramide baut. Die Hölle bricht los. Oder was ist, wenn zwei Kunden gleichzeitig nach demselben Artikel greifen und wer gewinnt? Wird es einen Kampf geben? Dies ist eine nicht threadsichere Sammlung. Es gibt viele Möglichkeiten, um Probleme zu vermeiden, aber alle erfordern eine Art Sperre oder eher einen expliziten Zugriff auf die eine oder andere Weise.
Stellen Sie sich andererseits ein Geschäft mit einem Angestellten an einem Schreibtisch vor, und Sie können nur über ihn einkaufen. Du stellst dich an und fragst ihn nach einem Gegenstand, er bringt ihn dir zurück und du verlässt die Schlange. Wenn Sie mehrere Artikel benötigen, können Sie auf jeder Rundreise nur so viele Artikel abholen, wie Sie sich erinnern können. Sie müssen jedoch vorsichtig sein, um den Angestellten nicht zu belästigen. Dies wird die anderen Kunden in der Schlange hinter Ihnen verärgern.
Betrachten Sie dies nun. Was ist, wenn Sie im Laden mit einem Angestellten ganz vorne mit dabei sind und den Angestellten fragen: "Haben Sie Toilettenpapier?", Und er sagt "Ja", und dann sagen Sie "Ok, ich". Ich melde mich bei Ihnen, wenn ich weiß, wie viel ich brauche. Wenn Sie dann wieder ganz vorne mit dabei sind, kann der Laden natürlich ausverkauft sein. Dieses Szenario wird durch eine threadsichere Sammlung nicht verhindert.
Eine threadsichere Sammlung garantiert, dass ihre internen Datenstrukturen jederzeit gültig sind, auch wenn von mehreren Threads aus darauf zugegriffen wird.
Für eine nicht threadsichere Sammlung gibt es keine solchen Garantien. Wenn Sie beispielsweise einem Binärbaum in einem Thread etwas hinzufügen, während ein anderer Thread damit beschäftigt ist, den Baum neu auszugleichen, gibt es keine Garantie dafür, dass das Element hinzugefügt wird, oder auch wenn der Baum danach noch gültig ist, kann er hoffnungslos beschädigt sein.
Eine threadsichere Sammlung garantiert jedoch nicht, dass sequentielle Operationen am Thread alle mit demselben "Snapshot" seiner internen Datenstruktur arbeiten. Wenn Sie also Code wie diesen haben:
if (tree.Count > 0)
Debug.WriteLine(tree.First().ToString());
Möglicherweise erhalten Sie eine NullReferenceException, da zwischen tree.Count
und ein tree.First()
anderer Thread die verbleibenden Knoten im Baum gelöscht hat, was bedeutet, dass zurückgegeben First()
wird null
.
In diesem Szenario müssen Sie entweder prüfen, ob die betreffende Sammlung einen sicheren Weg bietet, um das zu erhalten, was Sie möchten. Möglicherweise müssen Sie den obigen Code neu schreiben oder Sie müssen möglicherweise sperren.