A use-case for synchronized(new Object())

2019-06-18 07:18发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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.