2015-01-18 4 views
2

두 개의 동시 스레드에 의해 많이 액세스되는 두 개의 동기화 된 블록이 있습니다. 경합과 컨텍스트 전환을 줄이고 싶습니다. AtomicBoolean에서 CAS (CompareAndSet) 연산을 사용하여이를 수행 할 수 있습니까?CAS 작업을 사용하여 Java에서 동기화 된 블록을 작성하는 다른 방법이 있습니까?

예 : 내가 그 차이가 생각하지 않는 한 java.util.concurrent.locks.Lock 클래스를 사용하지 않으

private final Object lock = new Object(); 

// Thread A executing this 
public final void methodA() { 
    synchronized(lock) { 
     ... 
    } 
} 

// Thread B executing this 
public final void methodB() { 
    synchronized(lock) { 
     ... 
    } 
} 

. CAS를 사용하고 싶습니다.

private final AtomicBoolean flag = new AtomicBoolean(); 

while (!flag.compareAndSet(false, true)); 
try { 
    //your code here 
} finally { 
    flag.set(false); 
} 

당신은 모두 당신의 경쟁 시나리오에서 실제로 성능을 향상 않습니다 있는지 확인하기 위해 테스트해야합니다 :

+1

실제 병목 현상이 발생했는지 (예 : 프로파일 링을 통해) 추측 했습니까? – NPE

+0

예 병목 ​​현상입니다. 그것이 아니더라도 CAS를 통해 대안이 있는지 이해하고 싶습니다. 감사! –

+0

Richard - 동기화 된 블록 내에서 어떤 종류의 코드가 수행됩니까? 불리언에 대한 간단한 조작? –

답변

6

는 다음과 같은 방법으로 동기화 된 블록을 교체 할 수 있습니다. CAS는 경미한 경합에 가장 효과적으로 대응합니다.

@yshavit, the JIT may already perform that sort of optimisation for you에 의해 주석 처리되었으므로 다시 한번 테스트하는 것이 중요합니다.

+1

이것은 (또는 특정 조건하에있을 수 있음) 입증 된 단서가 있습니까? 'synchronized' 블럭? – NPE

+0

'lock' (그러므로 :'Object')에는 compareAndSet 메소드가 없습니다.이 코드는 컴파일되지 않습니다. 컴파일하지 않는 코드를 게시하는 것을 삼가 해주십시오. – specializt

+0

예, 가장 좋은 multithreding는 결석 한 것입니다;) –

2

실제 시나리오에 따라 CAS를 사용하는 스핀 록은 성능을 향상시킬 수도 있고 성능을 향상시킬 수도 없습니다. 블록의 코드가 다소 길고 시간이 오래 걸리면 동기화가 여전히 가장 안전한 선택이어야합니다.

다른 스레드가 다른 데이터 사본을 사용하고 잠금이 필요하지 않도록 데이터를 변경 가능하게 만들 수 있습니까?