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 사이에서 공유 변수 -- prev에 대한 모든 변경 사항은 ExtremePredecessor()에 표시됩니다.
다음과 같은 문제가 있습니다.
은 동기화 잠금과 매우 유사합니다.
prev
에 대한 동기 업데이트는 전체 대기열에 병목 현상을 발생시킵니다.#L1과 #L4 사이의 prev 값은 다른 스레드에서 변경했기 때문에 일치하지 않을 수 있습니다. 이로 인해 코드를 이해하기가 훨씬 더 어려워집니다.
Node p = prev;
을 사용하면 #L0 이후에는p
의 값을 동기화할 필요가 없습니다.p
#L1부터 #L4까지 일관됩니다.volatile
의 경우Java 언어 사양 휘발성 키워드
https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls- 8.3을 참조하세요. .1.4