2014-12-22 2 views
2

tryLock 메서드의 설명서에는 잠금을 얻거나 획득 할 수있는 비 차단 메서드
이 있습니다 (메서드를 호출 할 때 가능하다면).tryLock 메소드 - 비 차단 메소드?

하지만 궁금합니다. 어떻게 동시에 잠금을받을 수 있으며 동시에 보장 할 수 있습니까?
귀하의 방법 (tryLock)은 차단이 아닙니까?! 잠금 장치를 획득하면 코드가 보호되어야하는 코드 섹션에 액세스하려고 시도하는 사람이
인 것을 의미합니다 (행운이 아닐 경우
). 적어도 특정 시나리오에서는 차단해야합니다. 누구나 로직을 설명 할 수 있습니까?
? 순전히 논리적 인 관점에서 : 나는 확실히이이
모두에서 할 수있는 방법을 이해하지 않습니다 (이 방법은 차단하지 않는다는 것을 보장). 그들은 설정된 tryLock 자체의 코드 내 과정의 또 다른
스레드 ... 잠금을 획득

http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/Lock.html#tryLock%28%29

+0

글쎄요, 대부분의 최신 CPU에서 이것은 CAS (Compare And Swap)를 사용하여 이루어졌습니다 – fge

+0

@fge 글쎄요, 그것은 자바에서 어떻게 이루어 집니까? 나는 코드를 살펴 보았으나 아직 이해하지 못했다. 네이티브 메소드를 사용하고 있다고 말하는 겁니까? 나는 그들이 "프리미티브"'wait','notify','notifyAll'만으로 그것을한다고 생각했다. 그러나 그렇다면, 논리적으로 ... 나는 그것이 실제로 어떻게 행해질 수 있는지 정말로 모르겠습니다. –

+0

나는 대부분의 JVM이 그렇다고 의심 할 것이다. (확인되지 ​​않았지만 내 말을 듣지 마라.) 아마도 직접적인 어셈블리 코드는 아니 겠지만, 리눅스에서 퓨 텍스 같은 것을 사용하면 그 효과를 얻을 수 있습니다. – fge

답변

4

이러한 메커니즘의 대부분의 구현은 변수를 기반으로 기본 작업을 수행하기 위해 소싱 된 CAS CPU 명령어를 사용합니다. CAS는 Compare and Swap을 의미합니다. 이것들은 변수의 값을보고 당신이 기대하는 바라면 그것을 바꾼다. 이것은 다중 스레드 된 데이터에 대한 비교를 수행하는 스레드 안전 (비 차단/잠금) 방법을 제공합니다. 성공할 때까지

private int stored = 0; 
public int compareAndSwap(int expectedValue , int newValue) 

    if(expectedValue == stored) 
     stored = newValue; 

    return stored; 
} 

이 비 차단 메커니즘은 일반적으로 단지 위의 함수를 다시 시도 (반환 값이 예상 값) :

CAS의 명령은 원자 다음을 수행합니다. 재시도 루프가 매우 짧기 때문에 각 반복에서 인터럽트되는 스레드의 가능성은 매우 작습니다 (또는 실제로 OS 스케줄러는 불가능하게 만듭니다).

실제 자바 잠금 (Lock은 구현 된 인터페이스 임)은 추가 기능을 제공하기 때문에 훨씬 더 복잡합니다. 그러나 본질적으로 CAS 메커니즘은 대부분의 비 차단 (non-blocking) threadsafe 클래스의 기반이됩니다.

잠금 내부 작동에 관심이있는 경우 Java Concurrency in Practice은 훌륭한 소스입니다. Java 동시성이 수행 할 수있는 작업으로 부드럽게 시작하고 수행 방법을 개선하십시오. (비 자바 프로그래머에게도 훌륭한 소스입니다). 귀하의 질문은 15 장에서 다루어집니다.

+0

@monkjack 물론 네가 옳다. 고마워. (일부 버전의 CAS는 변경 여부를 나타내는 부울을 반환합니다). – Thirler

1

사용하지 않으면 당신이 그것을 차단해야하므로 코드의 보호 섹션에 액세스하려고하는 것을 의미한다 (운이 좋다면 적어도 특정 시나리오에서는 차단해야합니다.)

원하는 동작 인 경우 lock 메서드를 사용해야합니다. tryLock의 전체적인 점은 당신이 그것을 사용할 때 은 자물쇠가 이용 가능하지 않다면을 차단하고 싶지 않다는 것입니다.

을 구현의 방법의 측면에서

, 그것은 각각의 구현에 달려 있습니다 -. 그래서 당신은 당신이 관심있는 중 구현 봐야한다 나는 개인적으로 합리적인 그들이 어떤 것을 알고하지 않는 경우 사람들은, 내부적으로 synchronized를 사용하는 것을 생각 사용자 지정 코드는 이제까지 synchronized 블록 내에서 실행되었다 - 즉, 그것은 내부의 집 유지를위한 간단하게 차단할 수 있지만 잠금 자체의 기간 동안.

물론 적절한 기계 수준 명령어에 액세스 할 수있는 구현은 compare-and-swap 등을 사용할 수 있습니다 ... 도대체 AtomicBoolean.compareAndSet은 매우 간단한 버전으로 사용될 수 있습니다.

+0

1) "내부 집안일을 잠깐 동안 차단할 수는 있지만 잠금 자체는 지속되지 않습니다.">>> 이것은 추측 일뿐입니다 (그래서 나는 썼습니다 : "그들이 또 다른 스레드를 사용하지 않는다면 tryLock 자체의 코드 "); 2) compareAndSet >>> 그렇다면이 블록 자체는 비 블로킹이고, 그렇다면 어떻게 구현 되는가 ...?! 나는 조금 연구 할 것이다. 적어도 몇 가지 지침을 알려 주셔서 감사합니다. –

+0

@ peter.petrov :'tryLock'에서 다른 스레드를 사용하는 것에 대해 생각하지 않았습니다 ... 기본적으로 플랫폼 전용 머신에 의존 할 수있는'Atomic * 암호. –

+0

On 2) >>> 예, 네이티브 메소드를 사용합니다 : public final native boolean compareAndSwapInt는 안전하지 않은 클래스입니다. –

관련 문제