Graviton
Graviton

Reputation: 83254

lock statement not working when there is a loop inside it?

See this code:

public class multiply
{
    public Thread myThread;
    public int Counter
    {
        get;
        private set;
    }
    public string name
    {
        get;
        private set;
    }

    public void RunConsolePrint()
    {

        lock(this)
        {
        RunLockCode("lock");
        }


    }

    private void RunLockCode(string lockCode)
    {
        Console.WriteLine("Now thread "+lockCode+" " + name + " has started");
        for (int i = 1; i <= Counter; i++)
        {
            Console.WriteLine(lockCode+" "+name + ": count has reached " + i + ": total count is " + Counter);
        }
        Console.WriteLine("Thread " + lockCode + " " + name + " has finished");
    }
    public multiply(string pname, int pCounter)
    {
        name = pname;
        Counter = pCounter;
        myThread = new Thread(new ThreadStart(RunConsolePrint));
    }

}

And this is the test run code:

    static void Main(string[] args)
    {
        int counter = 50;

        multiply m2 = new multiply("Second", counter);
        multiply m1 = new multiply("First", counter);
        m1.myThread.Start();
        m2.myThread.Start();
        Console.ReadLine();
    }

I would expect that m2 must execute from start to finish before m1 starts executing, or vice versa, because of the lock statement. But the result I found was the call to lock first and lock second was intermingled together, i.e., something like this

Now thread lock First has started
Now thread lock Second has started
lock First: Count has reached 1: total count is 50
lock First: Count has reached 2: total count is 50
lock Second: Count has reached 1: total count is 50

What did I do wrong?

Upvotes: 3

Views: 2512

Answers (1)

tvanfosson
tvanfosson

Reputation: 532435

Each instance of the code is locking on a different object. Your lock object needs to be shared between all instances -- make it a static class variable.

private static object syncRoot = new object();
public void RunConsolePrint()
{
    lock(syncRoot)
    {
         RunLockCode("lock");
    }    
}

Upvotes: 21

Related Questions