AbstractQueuedSynchronizer
的Node
内部类中,对volatile Node prev
成员变量获取方法predecessor()
如下
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
在源码中,这里对volatile
类型的成员变量prev
的返回,是先把他赋值给一个中间变量p,然后拿p返回。
这种设计在AQS
的源码中很多地方都有涉及到,包括在其它源码中也经常看到对volatile
类型的变量先赋值给另外一个变量,然后把这个变量返回.
这样设计的目的是什么?
-------Wikipedia
The effect of
is less obvious in
predecessor()
这个方法里,Node p
. Please allow me to make the example a little more extreme:Assuming that 100 threads calls will change the value of prev, then between #L1 and #L4, any changes to the shared variable -- prev will be visible to extremePredecessor().
This will have the following problems:
is very similar to synchronization lock. Synchronous update of
prev
will cause performance loss, and prev will become a bottleneck for the entire Queue.The value of prev between #L1 and #L4 may be inconsistent because other threads have changed it. This makes it much more difficult to understand the code.
If used
Node p = prev;
那么#L0之后,就不需要同步p
的值了。#L1到#L4的p
is also consistent.For
volatile
, see:Java Language Spec volatile keyword
https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4