Gentlemen, I wondered why in the lock () keyword a reference to an object is needed. Without hesitation, I wrote code to check that it is for this link that is being blocked, the entire object containing the key, the word lock, or just the method itself in which this word occurs. For this, I made a class with 2 methods, one with the word lock, the other without. Created 4 class objects, each of which in different threads calls one method with one lock without blocking. And it turned out an opportunity.

  1. The expected behavior of me, if both methods without lock, must be such that the words will be output to the console in a chaotic order, but they are output sequentially, first one thread will output the word "Gleb", then the other, the word "Pavel" (the names of my cats) etc.

  2. The expected behavior, if there is a lock in the Thr1 () method, then the word Gleb should appear many times 100 times first, and then everything else. But this does not happen, and again everything is displayed in turn. Why?

  3. Still, what kind of object is blocked in the word lock and why should it be sent there at all, if it is clear where lock is there and blocked.

I apologize for the big question, but neither Google nor MSD help.

The code itself:

using System; using System.Threading; class a { object o = new object(); public void Thr1() { //lock (o) //{ for (int x = 0; x < 25; x++) { Thread.Sleep(200); Console.WriteLine("Pavel {0}", x); } //} } public void Thr2() { for (int x = 0; x < 25 ;x++ ) { Thread.Sleep(200); Console.WriteLine("Gleb{0}", x); } } } class b { public static a A = new a(); Thread t; Thread t1; public void StartThr1() { A.Thr1(); } public void StartThr2() { A.Thr2(); } public b() { t = new Thread(StartThr1); t.Start(); t.Join(); t1 = new Thread(StartThr2); t1.Start(); t1.Join(); } } class c { static void Main() { b B = new b(); b B1 = new b(); b B2 = new b(); b B3 = new b(); } } 

The lock block is locked to try both with it and without it. Thanks to all!!!

    2 answers 2

    Well, of course. First, you do not use this object anywhere, which is under lock. The object is transferred there so that no one else can change it while it is blocked by some stream. That is, if during code execution:

     public void Thr1() { lock (o) { for (int x = 0; x < 25; x++) { Thread.Sleep(200); Console.WriteLine("Pavel {0}", x); } } } 

    another thread wants to do something with object o , it cannot do this, it will wait until the object is released.

    Regarding why the output is consistent, you have the threads start sequentially:

     t = new Thread(StartThr1); t.Start(); t.Join(); t1 = new Thread(StartThr2); t1.Start(); t1.Join(); 

    Try this:

     t = new Thread(StartThr1); t1 = new Thread(StartThr2); t.Start(); t1.Start(); t.Join(); t1.Join(); 

      A key is passed from the MSDN to the Lock parameter, which will determine whether it was previously locked using Lock or not.

       lock("BLOCK_THIS") // Блокировка для любого следующего lock("BLOCK_THIS") { //my code } lock(typeof(MyClass)) // Блокировка для любого следующего lock(typeof(MyClass)) { // my code } lock(ObjectName) // Блокировка для любого следующего lock(ObjectName) { // my code } 

      Unlike the lock on the object, for all other options, there may be a problem that this lock key is used in another part of the code that should not intersect with the current lock and depend on it.