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
类型的变量先赋值给另外一个变量,然后把这个变量返回.
这样设计的目的是什么?
リーリー
------ウィキペディア
この方法
リーリーpredecessor()
では、Node p
の効果はそれほど明らかではありません。もう少し極端な例にすることをお許しください:100 個のスレッド呼び出しによって prev の値が変更されると仮定すると、#L1 と #L4 の間で、共有変数への変更はすべて、extremePredecessor() に表示されます。
これには次の問題があります:
は同期ロックによく似ています。
prev
への同期更新はキュー全体のボトルネックになります。#L1 と #L4 の間の prev の値は、他のスレッドによって変更されたため、矛盾している可能性があります。これにより、コードを理解することがさらに難しくなります。
Node p = prev;
を使用する場合、#L0 の後にp
の値を同期する必要はありません。 #L1 から #L4 までのp
も一致しています。volatile
については、次を参照してください:Java 言語仕様の揮発性キーワード
https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls- 8.3 .1.4