Wenn mehrere Threads auf die gleiche Datenstruktur zugreifen, dann muss man den Zugriff darauf zwischen diesen Threads synchronisieren. Besonders wenn es passieren kann da ein Thread lesend und ein anderer schreibend darauf zugreifen will. Macht man dies nicht ist ein Crash über kurz oder lang vorprogrammiert. Es macht sich nicht gut wenn man z.B. eine Liste ändert wärend ein anderer sich auf die Struktur verlässt. Dazu wird einem z.B. von C# die lock() Anweisung zu Verfügung gestellt. Damit wird sichergestellt dass alles was innerhalb der lock() Anweisung steht nur von einem Thread parallel ausgeführt werden kann. [c#] object _lock = new object(); UserDictionary _userList = new UserDictionary(); function ShowList() { lock(_lock) { foreach (User user in _userList) { [User ausgeben] } } } function AddUser(User user) { lock (_lock) { _userList.Add(user); } } [/c#] Damit ist gesichert dass während dem Anzeigen keine User hinzugefügt werden können, und somit der Iterator auf die sich foreach() verlässt während der Aktion konsistent ist. Nachteil ist jedoch, dass sich lesende Zugriffe mit lock() auch gegenseitig ausschließen und blockieren, da lock() dies nicht unterscheidet. Ein Fall wäre zum Beispiel ein WebForum was eine Liste der aktuellen Benutzer anlegt und sie auf jeder Seite anzeigen will, die Seite wird oft anzeigt, aber ein neuer kommt seltener hinzu bzw. wieder raus aus der Liste. Das .NET Framework bietet dazu die [b]ReaderWriterLock-Klasse[/b], damit kann eine Sychronisation abhängig vom Zweck realisieren, und somit sich selbst [b]blockierende Lesezugriffe verhindern[/b]. [c#] ReaderWriterLock _lock = new ReaderWriterLock(); UserDictionary _userList = new UserDictionary(); public void ShowUsers() { _lock.AcquireReaderLock(0) try { foreach (User user in _userList) { [User ausgeben] } } finaly { _lock.ReleaseReaderLock(); } } public void AddUser(User user) { _lock.AcquireWriterLock(0) try { _userList.Add(user); } finaly { _lock.ReleaseWriterLock(); } } [/c#] Damit ist sichergestellt alle Threads die Userliste gleichzeitig auslesen können, solange niemand schreiben darauf zugreift. [b]AquireWriterLock()[/b] wartet solange bis keine ReaderLocks mehr bestehen. [b]AquireReaderLock()[/b] wartet nur wenn noch auch ein WriterLock besteht. Auch kann man innerhalb eines ReaderLocks den lock mit [b]UpgradeToWriterLock()[/b] zu einem WriterLock hochstufen, um dann Daten zu ändern. Eine Hcohstufung des locks muss mit [b]DowngradeFromWriterLock()[/b] wieder Rückgängig gemacht werden. Weitere Informationen zu ReaderWriterLock() finden sich dazu natürlich in der MSDN Library [1]
[1] [url]http://msdn2.microsoft.com/System.Threading.ReaderWriterLock[/url]