0

I have good knowledge of synchronization internals and basic knowledge of volatile internals.

I have one query, which is follow-up to below SE question:

Why is volatile used in this example of double checked locking

I'm confused about one part. If I strictly follow above example, I have to add volatile to many variables but I am sure that all multi-threaded applications are not using this volatile + synchronized combination.

If synchronization is not guaranteeing memory consistency as per above example, what are the use cases of using combination of volatile variables with synchronization code?

Community
  • 1
  • 1
Aditya W
  • 652
  • 8
  • 20
  • 2
    Note: actually using double checked locking for a Singleton is a bad idea because a) Singleton, b) you can use an `enum` – Peter Lawrey Jun 27 '16 at 14:33
  • Definitely I use some other options like enum, Lazy loaders. Just added that question to provide context through some working code. My confusion is only about combination. – Aditya W Jun 27 '16 at 14:37
  • 1
    Double checked locking is used for lazy initialization of singleton objects. Also, volatile prevents an optimization that might occur: "This keyword prevents a subtle case where the compiler tries to optimize the code such that that the object is accessed before it is finished being constructed" (OCP Oracle® Certified Professional Java® SE 8 Programmer II) – John Estess Jun 27 '16 at 14:37
  • The simplest solution for a Singleton if you don't use other static methods or variables on the Singleton is to use an eager solution. An alternative is to use enums, or using the holder class idiom – Davide Lorenzo MARINO Jun 27 '16 at 14:40

2 Answers2

1

The combination of volatile and synchronized in that question/answer only applies to double-checked locking.

If you're not doing double-checked locking, and are accessing your shared variables always within the protection of the same synchronized monitor (which is how applications most commonly access shared variables, if they're not using the java.util.concurrent classes), then you don't need volatile.

In any case, this doesn't mean that double-checked locking is a good idea. Although the volatile + synchronized construct will make double-checked locking work, it doesn't offer any significant performance benefit, as you can also read in @alf's answer to the question you refer to.

Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • But in above scenario, the author is using the combination for memory consistency purpose. WIth a single lock condition, above code does not work. – Aditya W Jun 27 '16 at 14:36
  • @AdityaW above code is double-checked locking, and for double-checked locking (in which you access a shared variable outside the `synchronized` block) you need `volatile`. Most multithreaded code is (luckily!) not double-checked locking, as there little or no benefit to it. – Erwin Bolwidt Jun 27 '16 at 14:38
  • @AdityaW https://gist.github.com/anonymous/52e40d36d7e4caf321630bf71261a7b4 is perfectly fine. The problem in the double checked code arises from unsynchronized & not-volatile access (by a second thread) to the shared (and partially initialized but already visible) variable with 0 memory guarantees. – zapl Jun 27 '16 at 14:41
1

When a variable is defined volatile it is read from the main memory instead of registries.

So each processor will see the same value.

In the double check the variable is defined as volatile to be sure to check outside of synchronized block will intercept most of cases.

If the variable is not volatile the code will work, but if you have more processors you can go inside of the synchronized block more than needed (also when the variable is not null).

If all access to a variable are done in the synchronized block a volatile is not necessary at all.

Davide Lorenzo MARINO
  • 26,420
  • 4
  • 39
  • 56