Давайте представим себе некоторую магистраль(дорогу) от точки A до точки B по которой все время ездят разные автомобили. У магистрали только две точки - вход и выход, ответвлений нет. Кроме того она однополосная. Если бы она была двухполосной, мы могли бы просто представить бы ее как две независимыемые магистрали и считали бы каждую из них отдельной.
Итак, каждая машина может заезжать на магистраль[Enter] спустя некоторое время покидать ее[Leave]. Кроме того магистраль может быть ограниченной по колочиству машин, которое она в себе содержит(MaximumEntries).
Кроме магистрали есть еще и ремонтники. Они могут блокировать магистраль(Lock) и разблокировать ее(Unlock).
Блокировка магистрали заключается в том что
а) сначала закрывается вход
б) ожидается пока все машины "съедут" с магистрали.
И только после этого магистраль закрывается. При этом машины, которые хотят попасть на магистраль ждут некоторое время, пока она закончится ремонт и магситраль откроется. У этого ожидания есть два вариант:
а) Дорогу отремантирует и магистраль откроется, тогда машина заедет на магситраль(попытка входа будет успешной)
либо
б) Таймаут ожидания истечет до того как магистраль отремонтируют и тогда машина развернется обратно(и попытка входа провалится).
Где такое может понадобится? Ну положим естьь база со сложно зависимыми объектами, при чем эта база в основном читается пользователями. И положим нельзя допустить что бы то время, как какойто пользователь юзает базу для чтения, ктото ее изменил. В таком случае, пользователи "читающие" базу будут "машинами", а те службы, которые будуит ее периодически изменять - "ремотниками".
Или скажем некоторый объект, который асинхронным образом юзают разные потоки, и для которого есть еще и другие, "технические" потоки, которые периодически осуществляют запись на диск. Очевидно, что в этом случае для записи информации надо дождаться пока все рабочие потоки не закончат свою текущую работу с объектом, то есть пока они не "освободят" магистраль для проведления ремонтных работ.
О реализации. Делалась в торопях, и особо не тестировалась. Кроме того, возможно есть иные пути для реализации такой вот дороги. Буду рад услышать любую критику по этому поводу. Учитывая, что в этом деле я полный нуб, возможно так же существование некоторого стандартного объекта синхронизации. Если такой имеется, скажите мне об этом.
- Код: Выделить всё
- ' Date: 13 october 2006
 ' Author: ANDLL, Web: http://danasoft.ru
 ' Class DANAsoft.General.Synchronization.MultythreadWay
 Namespace DANAsoft.General.Synchronization
 Public Class MultythreadWay
 Public Const TIMEOUT_DEFAULT As Long = 1000
 Public MaximumEntries As Integer = -1
 Dim mThreads As New Collections.Generic.List(Of Threading.Thread)
 Dim mSyncLock As New Object
 Public Function EnterWay(Optional ByVal uTimeOut As Long = TIMEOUT_DEFAULT) As Boolean
 If Threading.Monitor.TryEnter(mSyncLock, uTimeOut) Then
 Try
 SyncLock mThreads
 If mThreads.Count > MaximumEntries And MaximumEntries <> -1 Then
 Throw New InvalidOperationException("The way is overflowed now")
 Else
 mThreads.Add(Threading.Thread.CurrentThread)
 End If
 End SyncLock
 Finally
 Threading.Monitor.Exit(mSyncLock)
 End Try
 Return True
 Else
 Return False
 End If
 End Function
 Public Sub LeaveWay()
 SyncLock mThreads
 mThreads.Remove(Threading.Thread.CurrentThread)
 End SyncLock
 End Sub
 Public Sub LockWay()
 SyncLock mThreads
 If mThreads.Contains(Threading.Thread.CurrentThread) Then
 Throw New Exception("Thread, that entered way, can not lock it.")
 End If
 Threading.Monitor.Enter(mSyncLock)
 End SyncLock
 Do
 SyncLock mThreads
 If mThreads.Count = 0 Then Exit Do
 Dim I As Threading.Thread
 For Each I In mThreads
 If Not I.IsAlive Then
 mThreads.Remove(I)
 Exit For
 End If
 Next
 End SyncLock
 Threading.Thread.Sleep(4)
 Loop
 End Sub
 Public Sub UnlockWay()
 Threading.Monitor.Exit(mSyncLock)
 End Sub
 End Class
 End Namespace










