Is the "lock" statement in C# time-consuming?
I have a method which has been called many times by other methods to hash data. Inside the method, some lock statements are used. Could you please let me know whether the lock statement is time-consuming and what is the best way to improve it.
P/S: I have been finding a way to avoid using the 开发者_运维技巧lock statement in this method.
Your question is not answerable. It depends entirely on whether the lock is contended or not.
Let me put it this way: you're asking "does it take a long time to enter the bathroom?" without telling us how many people are already in line to use it. If there is never anyone in line, not long at all. If there are usually twenty people waiting to get in, perhaps very long indeed.
The lock statement itself is not very time-consuming, but it may cause contention over shared data.
Followup: if you need to protect shared data, use a lock. Lock-free code is wicked difficult to do correctly, as this article illustrates.
You might find this article on threads interesting and relevant. One of the claims that it makes is "Locking itself is very fast: a lock is typically obtained in tens of nanoseconds assuming no blocking."
The lock statement itself is actually some syntactic sugar that creates and manages a Monitor object.
This in itself is usually not overly resource intensive, but can become a problem if you have multiple reads but no writes to your variable across multiple threads. Each read will have to wait for the other to finish before a read can complete. In scenarios where you might be getting the variable from multiple threads, but not setting it, you might want to look at using a ReaderWriterLockSlim object to manage asynchronous reads and writes.
I landed here for a slightly different question. In a piece of code that can be run as single threaded or multi threaded shoud I refactor the code to remove the lock statement (i.e. is the lock statement without parallelism costless)?
This is my test
class Program
{
static void Main(string[] args)
{
var startingTime = DateTime.Now;
(new Program()).LockMethod();
Console.WriteLine("Elapsed {0}", (DateTime.Now - startingTime).TotalMilliseconds);
Console.ReadLine();
}
private void LockMethod()
{
int a = 0;
for (int i = 0; i < 10000000; i++)
{
lock (this)
{
a++; // costless operation
}
}
}
}
To be sure that this code is not optimized I decompiled it. No optimizations at all (a++ changed to ++a).
RESULT: 1Mln of not contended locks acquirements takes about 160ms that is about 15ns for acquire a not contended lock.
精彩评论