Why do we pass an object to the statement lock?

Asked

Viewed 202 times

6

I’m working with multithreading and fell in a competition case. More than one thread accessed an I/O operation on the same file and so an exception was triggered. To solve the problem, I did so:

private static object padlock = new object();

private static void SaveFile(string content) {
    lock (padlock) {
        Directory.CreateDirectory(Dir);
        File.AppendAllText(FilePath, content);
    }
}

The object padlock is passed to the lock. I learned as if it were a cake recipe (which is horrible!). I don’t know why I need the object padlock.

2 answers

5


This has to do with atomicity. This ensures that the object cannot be accessed by other parts of the code concurrently until it is released, thus ensuring that the intermediate state it is in throughout the block is not accessible.

This is controlled by framework. Actually this code is only syntactic sugar for:

bool lockWasTaken = false;
var temp = padlock;
try {
    Monitor.Enter(temp, ref lockWasTaken);
    Directory.CreateDirectory(Dir);
    File.AppendAllText(FilePath, content);
} finally {
    if (lockWasTaken) Monitor.Exit(temp);
}

I put in the Github for future reference.

So it’s the class Monitor that controls such access.

Oftentimes use the lock loses the advantage of competition getting only the burden.

Note that the locking operation is only occurring in the application and not in the external resource (file). If it is allowed the external resource can still be accessed by other applications and give problem. Locking thus is only preventing other thread to run the same code at the same time.

1

This object is going "keep" the lock information.

When the first thread enters the method and calls the lock, the object obj (or padlock, in your example) is going to be with the status locked and prevent another thread from entering.

He’s just the object that holds this information.

From C# 4.0, the lock instruction is compiled this way:

bool lockWasTaken = false;
var temp = obj;
try
{
    Monitor.Enter(temp, ref lockWasTaken);
    // Operação thread unsafe...
}
finally
{
    if (lockWasTaken)
    {
        Monitor.Exit(temp); 
    }
}

Where the original method is this:

private static readonly Object obj = new Object();

// Dentro de um método XYZ
lock (obj)
{
    // Operação thread unsafe...
}

Reference

Browser other questions tagged

You are not signed in. Login or sign up in order to post.