Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should a lock variable be declared volatile?

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.

like image 416
Dor Cohen Avatar asked Jul 17 '12 12:07

Dor Cohen


People also ask

In what case would you declare a field as volatile?

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.

Can we declare variable as volatile?

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.

Does declaring a variable as volatile ensures thread safety?

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.

Which variable is volatile?

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.


2 Answers

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.

like image 186
Jon Skeet Avatar answered Oct 02 '22 23:10

Jon Skeet


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.

like image 3
RalphChapin Avatar answered Oct 02 '22 21:10

RalphChapin