Wenn Sie die MSDN-Dokumentation lesen, wissen Sie immer, ob eine Klasse Thread-sicher ist oder nicht. Meine Frage ist, wie Sie eine Klasse threadsicher gestalten? Ich spreche nicht über das Anrufen der Klasse mit Sperren Ich meine, ich arbeite für Microsoft create XXX class \ object und ich möchte sagen, es ist "Thread Safe", was müsste ich tun?Entwerfen einer Thread-Safe-Klasse
Antwort
Die einfachste und sicherste Art, einen Klassenfaden sicher zu machen, ist immutable. Das Schöne daran ist, dass Sie sich nie wieder mit dem Sperren beschäftigen müssen.
Rezept: Stellen Sie alle Instanzvariablen readonly
in C# (final
in Java).
- Ein unveränderliches Objekt, das im Konstruktor erstellt und initialisiert wurde, kann nicht geändert werden.
- Ein unveränderliches Objekt ist threadsicher. Zeitraum.
- Dies ist nicht das Gleiche wie eine Klasse mit nur Konstanten.
- Für änderbare Teile Ihres Systems müssen Sie weiterhin die Sperr-/Synchronisierungseigenschaften berücksichtigen und verarbeiten. Dies ist ein Grund, um unveränderliche Klassen überhaupt zu schreiben.
Siehe auch question.
Ich stimme mit Ihnen aus 2 Gründen nicht überein. 1. Es gibt verschiedene Arten von Unveränderlichkeit, mit denen wir arbeiten. http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx 2. "final" ist Java, Sie meinst du sie Konstanten machen? Wenn ja, stimme ich nicht zu. Alle Felder in den Klassenkonstanten zu machen unterscheidet sich sehr von der Tatsache, dass sie threadsicher sind. – ram
Unbeweglich zu sein ist nutzlos, wenn Sie Threads benötigen, um tatsächlich Daten zu teilen (was ich auf Grund der Frage annehme). – Gabe
Abschließend meine ich _make sicher, es hat einen Wert nach dem Konstruktor, und dieser Wert wird nur einmal zugewiesen_ gelesen. Es gibt viele Beispiele, die meinen Standpunkt beweisen, dh http://blogs.msdn.com/b/lucabol/archive/2007/12/06/creating-an- immutable-value-object-in-c- part -ii-making-the-class-better.aspx http://pebblessteps.com/post/Introduction-to-Immutability-in-C.aspx –
Um anzugeben, dass die Klasse threadsicher ist, geben Sie an, dass die internen Datenstrukturen in der Klasse nicht durch den gleichzeitigen Zugriff durch mehrere Threads beschädigt werden. Um diese Behauptung zu machen, müssten Sie das Sperren (Synchronisieren in Java) um kritische Code-Abschnitte innerhalb der Klasse einführen, was möglicherweise zur Beschädigung derselben führen könnte, die von mehreren gleichzeitigen Threads ausgeführt wurden.
Sie müssen die Verriegelung nicht unbedingt einführen. Mit System.Threading.Interlocked. * Können Sie einige schöne Dinge tun. – Spence
Ein anderer, vielleicht einfacherer Weg, diese Behauptung zu machen, besteht darin, alle Instanzvariablen 'readonly' zu markieren, um die Klasse unveränderlich zu machen. –
nicht generische ICollection
Klassen bieten Eigenschaften für die Fadensicherheit. IsSynchronized und SyncRoot. Leider können Sie IsSynchronized nicht einstellen. Sie können mehr über sie lesen here
In Ihren Klassen können Sie etwas ähnliches zu IsSynchronized und Syncroot, öffentliche Methoden/Eigenschaften allein und innerhalb der Methode Körper überprüfen für sie offen legen. Ihre IsSynchronized wird eine Nur-Lese-Eigenschaft sein, so dass, sobald die Instanz initialisiert wird, werden Sie nicht in der Lage sein, es zu ändern
bool synchronized = true;
var collection = new MyCustomCollection(synchronized);
var results = collection.DoSomething();
public class MyCustomCollection
{
public readonly bool IsSynchronized;
public MyCustomCollection(bool synchronized)
{
IsSynchronized = synchronized
}
public ICollection DoSomething()
{
//am wondering if there is a better way to do it without using if/else
if(IsSynchronized)
{
lock(SyncRoot)
{
MyPrivateMethodToDoSomething();
}
}
else
{
MyPrivateMethodToDoSomething();
}
}
}
Sie können mehr lesen über Thread schreiben sichere Sammlungen auf Jared Parson's blog
Die Dokumentation nicht schlagen vor, dass Klassen Thread-sicher sind, nur Methoden sind. Um zu bestätigen, dass eine Methode Thread-sicher ist, muss sie gleichzeitig von mehreren Threads aufgerufen werden können, ohne falsche Ergebnisse zu liefern (bei falschen Ergebnissen würde die Methode den falschen Wert zurückgeben oder das Objekt in einen ungültigen Zustand versetzt).
Wenn die Dokumentation sagt
Alle öffentlichen static (Shared in Visual Basic) Member dieses Typs sind thread sicher.
Es bedeutet wahrscheinlich, dass die statischen Member der Klasse den freigegebenen Zustand nicht mutieren.
Wenn die Dokumentation sagt
Jede Instanz Mitglieder sind nicht sicher fädeln garantiert.
bedeutet es wahrscheinlich, dass Methoden minimale interne Verriegelung haben.
Wenn die Dokumentation sagt
Alle öffentlichen und geschützten Mitglieder dieser Klasse sind Thread-sicher und verwendet gleichzeitig von mehreren Threads sein kann.
bedeutet es wahrscheinlich, dass alle Methoden, die Sie aufrufen können, die entsprechende Sperre in ihnen verwenden. Es ist auch möglich, dass die Methoden keinen gemeinsam genutzten Status mutieren oder dass es sich um eine blockierungsfreie Datenstruktur handelt, die eine gleichzeitige Verwendung ohne Sperren zulässt.
Bei Thread-sicheren Klassen handelt es sich ausschließlich um den Schutz der Daten (Instanzvariablen) in Ihrer Klasse. Die gebräuchlichste Methode ist das Schlüsselwort lock. Der häufigste Fehler Neuling ist die gesamte Klasse statt einer feingranularen Sperre verwenden sperren:
lock (this)
{
//do somethnig
}
Das Problem mit diesem ist, dass es eine große Leistungseinbußen geben kann, wenn die Klasse tut etwas Wichtiges. Die allgemeine Regel ist, so wenig wie möglich so kurze Zeit wie möglich zu sperren.
können Sie mehr hier lesen: lock keyword in C#
Wenn Sie multithreadnig mehr haben strarted zu verstehen, tief Sie auch einen Blick auf ReaderWriterLoch und Semaphore nehmen. Aber ich schlage vor, dass Sie nur mit dem Schlüsselwort lock beginnen.
Zusätzlich zu den anderen ausgezeichneten Antworten hier, auch einen anderen Blickwinkel.
Es ist nicht genug, dass die interne Datenstruktur der Klasse zu 100% Thread-sicher ist, wenn die öffentliche API mehrstufige Operationen hat, die nicht threadsicher verwendet werden können.
Betrachten Sie eine Listenklasse, die so erstellt wurde, dass unabhängig davon, wie viele Threads ausgeführt werden, unabhängig davon, wie viele Arten von Operationen ausgeführt werden, die interne Datenstruktur der Liste immer konsistent und OK ist.
Betrachten Sie diesen Code:
if (list.Count > 0)
{
var item = list[0];
}
Das Problem hierbei ist, dass der Inhalt der Liste zwischen dem Lesen der Count
Eigenschaft und das Lesen des ersten Elements durch die [0]
Indexer, könnte ein anderer Thread ausgeräumt .
Diese Art der Threadsicherheit wird normalerweise vergessen, wenn die öffentliche API erstellt wird. Hier besteht die einzige Lösung darin, dass der aufrufende Code bei jedem Zugriffstyp manuell etwas blockiert, um den Absturz des Codes zu verhindern.
Eine Möglichkeit, dies zu lösen, wäre für den Listentyp Autor sein, um typische Nutzungsszenarien zu berücksichtigen und die entsprechenden Methoden der Art hinzufügen:
public bool TryGetFirstElement(out T element)
dann würden Sie haben:
T element;
if (list.TryGetFirstElement(out element))
{
....
vermutlich TryGetFirstElement
arbeitet threadsicher und würde niemals true
zur gleichen Zeit zurückgeben, wie es den ersten Elementwert nicht lesen kann.
Es ist erwähnenswert, dass es in vielen Fällen möglich ist, dass eine Klasse verschiedene Arten von Thread-Sicherheit spezifiziert.Zum Beispiel wäre es viel billiger für eine 'IDictionary
- 1. Entwerfen einer GUI
- 2. Entwerfen einer Ähnlichkeitstabelle
- 3. Entwerfen einer XACML-API
- 4. Entwerfen einer Einstellungsstruktur
- 5. Entwerfen einer Objective-C-Klasse
- 6. Entwerfen einer Zustandsmaschine in C++
- 7. Entwerfen einer Benutzeroberfläche in Canvas mit HTML5
- 8. Methodiken zum Entwerfen einer einfachen Programmiersprache
- 9. Entwerfen einer Testklasse für eine benutzerdefinierte Barriere
- 10. Entwerfen einer Qt + OpenGL-Anwendung in Eclipse
- 11. Entwerfen einer gesättigten Summe mit Fensterfunktionen
- 12. Entwerfen einer GUI für eine J2ME-App
- 13. Hilfe beim Entwerfen einer C# 'Tabellenkalkulations-App'
- 14. Entwerfen einer Stock App möchte einen Ratschlag
- 15. Entwerfen einer PHP-Klasse. Der richtige Weg
- 16. Entwerfen einer anderen Art von Tag Cloud
- 17. Entwerfen einer SQL-Tabelle mit Hierarchie/Unterkategorien
- 18. Entwerfen einer Datenbank zum Verfolgen des Besitzers
- 19. Entwerfen einer asynchronen Taskbibliothek für ASP.NET
- 20. Desing-Muster zum Entwerfen einer Java-Bibliothek
- 21. Entwerfen einer Zwischendarstellung für einen Compiler
- 22. Entwerfen einer Multi-Thread-Matrix in Java
- 23. Entwerfen eines Stresstest-Frameworks
- 24. Entwerfen von JavaScript-Validierungsmethoden
- 25. Entwerfen verschachtelter Vorlagenklassen
- 26. Wenn Sie nicht in UML entwerfen, wofür entwerfen Sie dann?
- 27. Entwerfen eines Anwendungsprotokolls
- 28. Entwerfen eines Klassendiagramms
- 29. Entwerfen für EWGI-Kompatibilität
- 30. Entwerfen von Farbanpassungen
Siehe z.B. http://stackoverflow.com/questions/564319/achiting-thread-safety. –
Ich versuche nicht, die Threadsicherheit zu überprüfen. Ich frage, was Sie berücksichtigen müssen, um es zu entwerfen ... – Shane