-2

I am trying to understand these of monitor in C# and tried out the following program.

Basically, this is all it tries to do:

  1. Thread 1 acquires lock on an object (done in method m)

  2. Thread 2 invokes another method which changes the state of locked object when the lock is still held by Thread 1. (Main thread does this by calling anotherMethod)

Ideally, one would expect that when a lock is held on an object, no other thread can alter its state during the lifetime of the lock. But that doesn't seem to be happening.

class Program
{
    private int x = 0;

    void Method()
    {
        lock (this)
        {
            Thread.Sleep(5000);
        }
    }

    void AnotherMethod()
    {
        x++;
        Console.WriteLine("entered");
    }

    static void Main(string[] args)
    {
        Program p = new Program();
        Thread t = new Thread(() => p.Method());
        t.Start();
        p.AnotherMethod();
    }
}

What good is a lock if it doesn't freeze the state of object when it is in force?

Also, please help me understand this : if the sole purpose of lock statement is to mark some code as critical section, whats the significance of acquiring lock against an object?

Aadith Ramia
  • 10,005
  • 19
  • 67
  • 86
  • The lock is only useful if you are also trying to acquire the lock from other threads. It is your responsibility to control what you do or do not change, based on whether you do or do not acquire the lock. – Andrew Barber Jan 25 '15 at 05:57
  • I assume you've read intro articles on MSDN - [lock](https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx) and [Synchronization](https://msdn.microsoft.com/en-us/library/ms173179.aspx)... Based on that I think you have not pasted your complete samples. – Alexei Levenkov Jan 25 '15 at 05:57
  • @Alexei thats the whole code i treid out – Aadith Ramia Jan 25 '15 at 05:58
  • @Alexei if lock is just to mark code as crticial section, why lock against a specific object? could you please help me understand this? – Aadith Ramia Jan 25 '15 at 06:01
  • Side note: you may want to adjust your question so it shows what you've already tried/read (like related [questions](http://stackoverflow.com/questions/7264841/thread-synchronization-why-exactly-this-lock-isnt-enough-to-synchronize-thread?rq=1))... Right now it looks like nicely written question showing no research. – Alexei Levenkov Jan 25 '15 at 06:02
  • No I can't... To understand locking in general CS sense you can try to imagine room with lock on it and there is only one key which person opening the door take when entering and locks from inside... The recommendations on proper using `lock` statement spelled out in the articles I've linked - I don't think I can do better. – Alexei Levenkov Jan 25 '15 at 06:08

2 Answers2

0

You really might want to read up on multi-threaded programming (and the pitfalls thereof).

All a lock does is acquire a mutex — a mutually exclusive semaphor. All that means is that no other thread app an acquire that same mutex until the current owner relinquishes it.

It has no meaning save that which has been mutually agreed upon. All a lock statement means is that once a resource has been locked, no other thread trying to acquire the same resource via lock will be able to do so until the owning thread relinquishes control of the resource.

Since your m() method Uses lock but your anotherMethod() doesn't, your anotherMethod() is completely unaware of the existence of the lock.

Further, you might want to read this question: Why is lock(this) {...} bad?

Community
  • 1
  • 1
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
0

The lock will lock an instance of an object. It seems you create a new instance of your program inside the static method? So you have locked the static instance. Which is different from your p instance.The best way to use a lock is to define separate object to lock inside your shared class. If you lock you implementation classes you may run into concurrency issues.

For example , to lock access to a particular code block in my class.

public class SharedCounter
{
      Object lockObj = new Object();
      Private int count =0;

      public void Increment()
      {
           Lock(lockObj)
           {
                 count++;
            }
       }
}

Now you could safely pass an instance of this class into multiple threads and the count would be safely incremented as each thread called increment.(although for this example you would use interlocked as it simply increments an int)

But hopefully this makes sense.

Noel
  • 567
  • 1
  • 4
  • 11