May Volatile Be in User Defined Types to Help Writing Thread-Safe Code

How to write a simple thread-safe class using a volatile variable?

The question was not easy for me, because I thought (incorrectly) that knowing everything about the happens-before relation gives one a complete understanding of the Java Memory Model - and the semantics of volatile.

I found the best explanation in this document:
"JSR-133: JavaTM Memory Model and Thread Specification"

The most relevant fragment of the above document is the section "7.3 Well-Formed Executions".

The Java Memory Model guarantees that all executions of a program are well-formed. An execution is well-formed only if it

  • Obeys happens-before consistency
  • Obeys synchronization-order consistency
  • ... (some other conditions must also be true)

Happens-before consistency is usually enough to come to a conclusion about the program behavior - but not in this case, because a volatile write doesn't happen-before another volatile write.

The MyIntegerHolder with volatile is thread-safe, but it's safety comes from the synchronization-order consistency.

In my opinion when Thread B is about to set the value to 7, A doesn't inform B of everything it has done until that moment (as one of the other answers suggested) - it only informs B about the value of the volatile variable. Thread A would inform B about everything (assigning values to other variables) if the action taken by Thread B was read and not write (in that case, there would exist the happens-before relationship between the actions taken by these two threads).

Volatile and multithreading: is the following thread-safe?

It is probably sort of thread-safe.

Thread safety tends to depend on context. Updating a bool is always thread safe, if you never read from it.
And if you do read from it, then the answer depends on when you read from it, and what that read signifies.

On some CPUs, but not all, writes to an object of type bool will be atomic. x86 CPUs will generally make it atomic, but others might not. If the update isn't atomic, then adding volatile won't help you.

But the next problem is reordering. The compiler (and CPU) will carry out reads/writes to volatile variables in the order specified, without any reordering. So that's good.

But it makes no guarantee about reordering one volatile memory access relative to all the non-volatile ones. So a common example is that you define some kind of flag to protect access to a resource, you make the flag volatile, and then the compiler moves the resource access up so it happens before you check the flag. It's allowed to do that, because it's not reordering the internal ordering of two volatile accesses, but merely a volatile and a non-volatile one.

Honestly, the question I'd ask is why not just do it properly?
It is possible that volatile will work in this situation, but why not save yourself the trouble, and make it clearer that it's correct? Slap a memory barrier around it instead.

What happens if a volatile variable is written from 2 threads?

The keyword volatile is used to ensure that changes to your Object will be seen by other Threads.
This does not enforce, that non-atomic operations on the Object will be performed without an other Thread interfering before the operation is finished.
For enforcing this you will need the keyword synchronized.

Java: volatile enough to make classes threadsafe?

Reads and writes of references are always atomic in Java, so there is no danger of, for example, seeing the reference in some half-updated state. If this is what you mean by "thread safe" then the operation is thread safe with or without the keyword.

But volatile is not about atomicity, it affects whether threads can cache writes locally. volatile would force writes to be written back to main memory and be visible to other threads. If that is what you mean by thread-safe, then yes you need this keyword.

volatile itself does not affect whether method calls on foo exclude other threads or not. If that's what you mean you want to use synchronized, and in a different place.

Does volatile mean it is thread safe

volatile means that the value will always be fresh; if another thread put a new object into the variable before you, you will see that object.

It does not change the behavior of the value; you cannot magically make an object thread-safe.

When should the volatile keyword be used in C#?

I don't think there's a better person to answer this than Eric Lippert (emphasis in the original):

In C#, "volatile" means not only "make sure that the compiler and the
jitter do not perform any code reordering or register caching
optimizations on this variable". It also means "tell the processors to
do whatever it is they need to do to ensure that I am reading the
latest value, even if that means halting other processors and making
them synchronize main memory with their caches".

Actually, that last bit is a lie. The true semantics of volatile reads
and writes are considerably more complex than I've outlined here; in
fact they do not actually guarantee that every processor stops what it
is doing
and updates caches to/from main memory. Rather, they provide
weaker guarantees about how memory accesses before and after reads and
writes may be observed to be ordered with respect to each other
.
Certain operations such as creating a new thread, entering a lock, or
using one of the Interlocked family of methods introduce stronger
guarantees about observation of ordering. If you want more details,
read sections 3.10 and 10.5.3 of the C# 4.0 specification.

Frankly, I discourage you from ever making a volatile field. Volatile
fields are a sign that you are doing something downright crazy: you're
attempting to read and write the same value on two different threads
without putting a lock in place. Locks guarantee that memory read or
modified inside the lock is observed to be consistent, locks guarantee
that only one thread accesses a given chunk of memory at a time, and so
on. The number of situations in which a lock is too slow is very
small, and the probability that you are going to get the code wrong
because you don't understand the exact memory model is very large. I
don't attempt to write any low-lock code except for the most trivial
usages of Interlocked operations. I leave the usage of "volatile" to
real experts.

For further reading see:

  • Understand the Impact of Low-Lock Techniques in Multithreaded Apps
  • Sayonara volatile

Is a volatile int in Java thread-safe?

Yes, you can read from it and write to it safely - but you can't do anything compound such as incrementing it safely, as that's a read/modify/write cycle. There's also the matter of how it interacts with access to other variables.

The precise nature of volatile is frankly confusing (see the memory model section of the JLS for more details) - I would personally generally use AtomicInteger instead, as a simpler way of making sure I get it right.



Related Topics



Leave a reply



Submit