In a recent answer I suggested that it is possible to achieve the functionality of volatile
by synchronizing
on the object containing the variable we need to be volatile
(asker does not have access to the variable in code).
This got me thinking that I actually don't need to block on the containing object, I just need to achieve a memory barrier. As synchronized
achieves both synchronisation and a memory barrier, if all I need is the memory barrier (as in this case) would it actually be better to use synchronized(new Object())
to achieve my memory barrier and ensure the lock is never contended?
In addition to @assylias's very good point, also consider that synchronized
does not achieve a memory barrier by specification. It is only the case that this is how it is implemented on today's typical CPU-memory architectures. The specification only guarantees what happens when two threads acquire the same lock.
Anyway, if you don't care about the specification, but only about the real-world implementations, then why not introduce your own volatile
variable and simply write to it whenever you want a memory barrier? It is irrelevant which volatile
you write to, as long as we're talking about a constrained set of architectures which is implied by your synchronized(new Object())
idea.
As explained here: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#synchronization
synchronized(new Object()) is considered a noop and may be removed entirely by the compiler. You won't get a memory barrier out of it.
would it actually be better to use synchronized(new Object())
to achieve my memory barrier and ensure the lock is never contended?
Nop. The JVM can easily prove that this lock can't be accessed by two threads (since it is a thread-local variable) and will almost certainly turn it into a no-op, i.e. completely remove the synchronized
statement.