I am writing a simple program in which there are several threads, and each of them in turn gets access to a shared resource and performs some kind of action. I understand that Wait () frees the blocking object, and blocks the execution of the thread until another thread calls Pulse (), well, Pulse () allows the thread in Wait () to execute further.
Resource
class Sourse { object objLock = new object(); public void toDo(string name) { lock (objLock) { Monitor.Pulse(objLock); Console.WriteLine($"Поток {name} получил доступ и выполняется."); Monitor.Wait(objLock); } } } My threads
class MyThread { Thread thrd; static Sourse srs = new Sourse(); public MyThread(string name) { thrd = new Thread(this.Run); thrd.Name = name; thrd.Start(); } public void Run() { while (true) { srs.toDo(thrd.Name); Thread.Sleep(1000); } } } And the entry point into the program:
class Program { static void Main(string[] args) { MyThread first = new MyThread("1"); MyThread second = new MyThread("2"); MyThread third = new MyThread("3"); } } If I organize the code in the way I showed above - several threads are executed simultaneously, the actions are not synchronized in any way. If I write this way:
lock (objLock) { Monitor.Wait(objLock); Console.WriteLine($"Поток {name} получил доступ и выполняется."); Monitor.Pulse(objLock); } That is, of course, all threads will be blocked without performing any actions, and everyone will stand in wait. The poorly needed result I need is achieved if I organize the resource as follows:
bool key = true; lock (objLock) { if(key == true) { Console.WriteLine($"Поток {name} получил доступ и выполняется"); key = false; Monitor.Wait(objLock); } else { key = true; Monitor.Pulse(objLock); } } but such a record looks like a crutch crutch, and moreover, does not meet all the requirements, since at the start of the program, 2 threads immediately get access and execute simultaneously, and this should not be the case. The question is: how to implement sequential access from multiple threads to a shared resource so that the resource is always available to only one thread? Is it possible to achieve the result I need without such booleans?