Why JDK source code accepts "final" copy of "volatile" instances

I read the JDK source code about ConcurrentHashMap.

But the following code confused me:

public boolean isEmpty() { final Segment<K,V>[] segments = this.segments; ... } 

My question is:

"this.segments" is declared:

 final Segment<K,V>[] segments; 

So, here, at the beginning of a method declared as a reference to the same type, point to the same memory.

Why did the author write it like this? Why didn't they use this.segments directly? Is there any reason?

+74
java
31 Oct. '12 at 10:29
source share
3 answers

This is an idiom typical of non-blocking code with volatile variables. On the first line, you read volatile once, and then work with it. Meanwhile, another thread might update volatile , but you are interested in the value just read.

In addition, even if the member variable is not volatile, but final, this idiom is related to CPU caches, because reading from the stack location is safer for the cache than reading from a random heap location. There is also a higher likelihood that a local variable will be bound to the CPU register.

There is actually some disagreement in this latter case, as the JIT compiler will usually take care of these issues, but Doug Lee is one of the guys who adheres to it in a general way.

+94
Oct 31 '12 at 10:31
source share

I assume that this is needed to consider performance, so we only need to get the field value once.

You can reference the single idiom from Joshua Bloch's effective java

His singleton is here:

 private volatile FieldType field; FieldType getField() { FieldType result = field; if (result == null) { synchronized(this) { result = field; if (result == null) field = result = computeFieldValue(); } } return result; } 

and he wrote:

This code may seem a bit confusing. In particular, the need for the result of a local variable may be unclear. What this variable does is make sure that the field is read only once in the normal case, when it is already initialized. Although this is not strictly necessary, it can improve performance and is more elegant by the standards applied to low-level concurrent programming. On my machine, the above method is about 25% faster than the obvious version without a local variable .

+19
Oct 31 '12 at 10:52
source share

It can reduce the size of the byte code - access to a local variable is shorter in byte code than access to an instance variable.

The overhead of optimizing runtime can also be reduced.

But not one of them is significant. This is more about code style. If you feel comfortable with instance variables, by all means. Doug Lee is probably more comfortable with local variables.

+4
Oct 31 '12 at 16:41
source share



All Articles