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
Dalam kaedah ini
predecessor()
, kesanNode p
tidak begitu ketara. Tolong izinkan saya menjadikan contoh itu lebih ekstrem:Dengan mengandaikan bahawa 100 rangkaian panggilan akan menukar nilai prev, kemudian antara #L1 dan #L4, sebarang perubahan pada pembolehubah kongsi -- prev akan kelihatan kepada extremePredecessor().
Ini akan mempunyai masalah berikut:
sangat serupa dengan kunci penyegerakan. Kemas kini segerak kepada
prev
akan menyebabkan kehilangan prestasi sebelum ini menjadi hambatan untuk keseluruhan Baris.Nilai sebelumnya antara #L1 dan #L4 mungkin tidak konsisten kerana urutan lain telah mengubahnya. Ini menjadikannya lebih sukar untuk memahami kod.
Jika anda menggunakan
Node p = prev;
, maka selepas #L0, tidak perlu menyegerakkan nilaip
.p
dari #L1 hingga #L4 juga konsisten.Untuk
volatile
, lihat:Kata kunci tidak menentu Spesifikasi Bahasa Java
https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls- 8.3 .1.4