2 개의 AtomicReferences에 대해 스왑 메소드를 구현하려고했습니다.2 개의 다른 AtomicReferences에서 2 개의 값을 교환하십시오.
public void swap(AtomicReference<Object> a, AtomicReference<Object> b) {
while (true) {
Object value1 = a.get();
Object value2 = b.get();
if (a.compareAndSet(value1, value2) && b.compareAndSet(value2, value1)) return;
}
}
제 생각에는이 해결책이 올바르지 않습니다. 여러 스레드가 동시에이 방법을 사용하는 경우, 다음과 같은 시나리오로 이어질 수 :
T1: ...get(); get(); compareAndSet() == true //-> BREAK (scheduler)
T2: ...get(); get(); compareAndSet() == true; compareAndSet() == true; return;
이 의미, T1은 a
의 값을 설정했지만 B의 값을 설정하여 실패합니다. T1은 AtomicReference가 설정된 경우 EVEN 프로세스를 반복합니다.
당신 같은 사람이 더 좋은 아이디어를 갖고 있습니까? 이것을 어떻게 구현합니까? 하나의 AtomicReference 만 있으면 쉽게 될 것입니다. 어쩌면 그것은 2 AtomicReference를 사용하는 것이 가능하지 않으며 Object []를 가리키는 AtomicReference를 사용하는 것을 고려해야합니다.
스칼라에서이 방법은 원자 블록을 가지고 있기 때문에 구현하기가 쉽습니다.
class Swappy[A](_a: A, _b: A) {
@volatile
var a = Ref(_a)
@volatile
var b = Ref(_b)
def swap(): Unit = {
atomic {
implicit tx =>
val tmp = a
a = b
b = tmp
}
}
def elems: (A, A) = (a.single(), b.single())
}
스칼라에 대해 모르겠다.하지만 스칼라가 저레벨 CPU의 원자 명령을 자체적 인 항목으로 래핑하지 않는 한, 솔직히 그것이 어떻게 작동 하는지를 알지 못한다. – doublep
사실 그것은 "실제"저급 원자량이 아닙니다. 그러나 블록의 끝에서 모든 것이 정확하다면 영향을받는 값이 변경되지 않으면 자체 검사를합니다. 그렇지 않다면, 그것은 되돌아 가서 원자 블록의 시작부터 시작합니다. :) – codepleb
가능한 복제본 [Java Atomicity & 좋은 비교 및 스왑 프레임 워크?] (http://stackoverflow.com/questions/14771174/java-atomicity-a-good-compare-and-swap-framework) – rbp