Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# threading - Lock Object

I am trying to lock a "boxed" object in a c# app, is this not possible?

    class t
    {
        System.Object t_x = new object();

        public t(int p)
        {
            t_x = p;

        }

        public void w()
        {
            lock (t_x)
            {
                for (int i = 0; i < 4; i++)
                {

                    {
                        t_x = ((int)t_x) + 1;
                        Console.WriteLine(t_x);
                        Thread.Sleep(1000);
                    }
                }
            }
        }
    }

In another class I can start 2 threads:

        Thread b1 = new Thread(new ThreadStart(t1.w));
        b1.Start();
        Thread b2 = new Thread(new ThreadStart(t1.w));
        b2.Start();

However the portion is not locked. When I lock an arbitrary object (i.e. one created and not modified as object a=new object()) it locks well. Is boxing operation somehow "depromotes" my Object??

like image 244
paul simmons Avatar asked Aug 17 '09 11:08

paul simmons


2 Answers

No, you can't do this - the lock block is shorthand for the following:

try(Monitor.Enter(lockObject))
{
    //critical section
}
finally
{
    Monitor.Exit(lockObject)
}

The documentation for Monitor.Enter states, "Use Monitor to lock objects (that is, reference types), not value types. When you pass a value type variable to Enter, it is boxed as an object. If you pass the same variable to Enter again, it is boxed as a separate object, and the thread does not block"

like image 105
Lee Avatar answered Sep 19 '22 11:09

Lee


You need to create a separate lock object. The problem is that you re-assign t_x inside the loop. Assuming thread b1 gets inside the loop before b2 gets to the lock statement, b2 will be allowed inside the lock statement because, by that time, t_x will be a new object that does not have a lock on it.

like image 37
AgileJon Avatar answered Sep 20 '22 11:09

AgileJon