I have the following Lock statement:
private readonly object ownerLock_ = new object();
lock (ownerLock_)
{
}
Should I use volatile keyword for my lock variable?
private readonly volatile object ownerLock_ = new object();
On MSDN I saw that it usually used for a field that is accessed without locking, so if I use Lock I don't need to use volatile?
From MSDN:
The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock statement to serialize access.
The volatile keyword indicates that a field might be modified by multiple threads that are executing at the same time. The compiler, the runtime system, and even hardware may rearrange reads and writes to memory locations for performance reasons.
volatile is a keyword that must be used when declaring any variable that will reference a device register. If this is not done, the compile-time optimizer might optimize important accesses away.
Unlike synchronized methods or blocks, it does not make other threads wait while one thread is working on a critical section. Therefore, the volatile keyword does not provide thread safety when non-atomic operations or composite operations are performed on shared variables.
Volatile variables have the visibility features of synchronized but not the atomicity features. The values of the volatile variable will never be cached and all writes and reads will be done to and from the main memory.
If you're only ever accessing the data that the lock "guards" while you own the lock, then yes - making those fields volatile is superfluous. You don't need to make the ownerLock_
variable volatile either. (You haven't currently shown any actual code within the lock
statement, which makes it hard to talk about in concrete terms - but I'm assuming you'd actually be reading/modifying some data within the lock
statement.)
volatile
should be very rarely used in application code. If you want lock-free access to a single variable, Interlocked
is almost always simpler to reason about. If you want lock-free access beyond that, I would almost always start locking. (Or try to use immutable data structures to start with.)
I'd only expect to see volatile
within code which is trying to build higher level abstractions for threading - so within the TPL codebase, for example. It's really a tool for experts who really understand the .NET memory model thoroughly... of whom there are very few, IMO.
If something is readonly
it's thread-safe, period. (Well, almost. An expert might be able to figure out how to get a NullReferenceException on your lock
statement, but it wouldn't be easy.) With readonly
you don't need volatile
, Interlocked
, or locking. It's the ideal keyword for multi-threading, and you should use it where ever you can. It works great for a lock object where its big disadvantage (you can't change the value) doesn't matter.
Also, while the reference is immutable, the object referenced may not be. "new object()" is here, but if it was a List
or something else mutable--and not thread-safe--you would want to lock the reference (and all other references to it, if any) to keep the object from changing in two threads at once.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With