Java 휘발성 참조와아토믹 레퍼런스
와의 차이가 있습니까?volatile오브젝트 참조 및AtomicReference만약 내가 그냥 쓸까 봐get()그리고.set()- 로부터 복사AtomicReference?
간단한 대답은 "아니오"입니다.
패키지의 메뉴얼로부터.견적 내용:
atomics의 액세스와 업데이트에 대한 메모리 효과는 일반적으로 휘발성 물질에 대한 규칙을 따릅니다.
get를 읽으면 기억력이 있다volatile변수.set를 쓰는(메모리) 메모리 효과가 있다.volatile변수.
덧붙여서, 그 서류는 매우 훌륭하고, 모든 것이 설명되고 있습니다.
AtomicReference::lazySet 새로운 (Java 6+) 조작으로, 를 통해 도달할 수 없는 의미를 가지고 있습니다.volatile변수입니다.상세한 것에 대하여는, 이 투고를 참조해 주세요.
아니, 없어.
AtomicReference에 의해 제공되는 추가 파워는 compareAndSet() 메서드와 친구입니다.이러한 메서드가 필요하지 않은 경우 휘발성 참조는 AtomicReference.set() 및 .get()과 동일한 의미를 제공합니다.
몇 가지 차이점과 단점이 있습니다.
의 사용방법
AtomicReferenceget/set은 휘발성 필드(javadoc 스테이트)와 동일한 JMM 의미를 가지지만AtomicReference는 참조 주위의 래퍼이므로 필드에 대한 접근은 포인터 추적을 더 필요로 합니다.메모리 설치 공간은 다음과 같이 증가합니다(압축된 OOP 환경을 가정하면 대부분의 VM에 해당).
- 휘발성 기준 = 4b
AtomicReference= 4b + 16b (12b 객체 헤더 + 4b 참조 필드)
AtomicReference는 휘발성 참조보다 풍부한 API를 제공합니다.volatile reference API를 회복하려면AtomicFieldUpdater또는 Java 9의 경우VarHandle또, 똑바로 손을 뻗을 수도 있습니다.sun.misc.Unsafe가위를 들고 뛰는 걸 좋아하신다면요AtomicReference그 자체는 다음과 같이 실장됩니다.Unsafe.
그렇다면, 어느 쪽을 선택하는 것이 좋은가?
- get/set만 하면 되나요?휘발성 필드, 단순한 솔루션 및 최저 오버헤드를 고수합니다.
- 추가 기능이 필요하십니까?코드의 퍼포먼스(속도/메모리 오버헤드)에 민감한 부분인 경우 다음 중 하나를 선택합니다.
AtomicReference/AtomicFieldUpdater/Unsafe가독성과 퍼포먼스 향상에 따른 리스크에 대해 비용을 지불하는 경향이 있습니다.만약 여기가 민감한 지역이 아니라면AtomicReference라이브러리 라이터는 일반적으로 대상 JDK, 예상되는 API 제한, 메모리 제약 등에 따라 이러한 방법을 혼합하여 사용합니다.
JDK 소스 코드는 이러한 혼란에 대한 가장 좋은 답변 방법 중 하나입니다.AtomicReference의 코드를 보면 객체 저장에 volatie 변수를 사용합니다.
private volatile V value;
따라서 AtomicReference에서 get() 및 set()만 사용할 경우 휘발성 변수를 사용하는 것과 같습니다.그러나 다른 독자들이 코멘트했듯이 AtomicReference는 추가적인 CAS 시멘틱스를 제공합니다.따라서 먼저 CAS 시멘틱스를 사용할지 여부를 결정하고 사용할 경우에만 Atomic Reference를 사용합니다.
AtomicReference 는 플레인 휘발성 변수에서는 제공되지 않는 추가 기능을 제공합니다.API Javadoc을 읽어보셨기 때문에 알 수 있을 것입니다만, 일부의 조작에 도움이 되는 잠금 기능도 갖추고 있습니다.
단, 이 추가 기능이 필요 없는 한 플레인 사용을 권장합니다.volatilesyslog.syslog.syslog.
gets와 sets만을 사용하는 경우에도 Atomic Reference를 선택하는 것이 좋습니다.
volatile의 예:
private volatile Status status;
...
public setNewStatus(Status newStatus){
status = newStatus;
}
public void doSomethingConditionally() {
if(status.isOk()){
System.out.println("Status is ok: " + status); // here status might not be OK anymore because in the meantime some called setNewStatus(). setNewStatus should be synchronized
}
}
Atomic Reference 를 사용한 실장에서는, 카피 온 라이트 동기화가 무료로 제공됩니다.
private AtomicReference<Status> statusWrapper;
...
public void doSomethingConditionally() {
Status status = statusWrapper.get();
if(status.isOk()){
System.out.println("Status is ok: " + status); // here even if in the meantime some called setNewStatus() we're still referring to the old one
}
}
다음과 같이 대체하면 적절한 복사본을 계속 가질 수 있다고 말할 수 있습니다.
Status status = statusWrapper.get();
포함:
Status statusCopy = status;
그러나 두 번째 것은 향후 "코드 클리닝" 중에 누군가가 실수로 제거할 가능성이 높습니다.
언급URL : https://stackoverflow.com/questions/281132/java-volatile-reference-vs-atomicreference
'source' 카테고리의 다른 글
| SQLite 또는 MySql?어떻게 결정해요? (0) | 2023.01.05 |
|---|---|
| SQL 주입 MariaDB python CTF (0) | 2023.01.05 |
| 기술적으로, 가변 함수는 어떻게 작동합니까?printf는 어떻게 작동합니까? (0) | 2023.01.05 |
| 웹 서버에서 중첩된 산술 MySQL 쿼리에 대한 문제 (0) | 2023.01.05 |
| Python 객체가 문자열인지 확인하는 방법 (0) | 2023.01.05 |