Java 동기화 된 잠금 장치가 순서대로 취해 졌는지 확인하십시오.
-
05-07-2019 - |
문제
동기화 된 메소드를 통해 하나의 목록에 액세스하는 두 개의 스레드가 있습니다. 우리는 할 수 있습니까?
a) 런타임에 의존하여 각각이 시도한 순서에 따라 각각의 방법에 대한 액세스를받을 수 있도록
b) VM은 다른 규칙을 따릅니다
c) 요청을 직렬화하는 더 좋은 방법이 있습니까?
해결책
아니요, Synchronized는 모든 순서로 액세스를 제공합니다 (JVM 구현에 따라 다름). 이로 인해 일부 시나리오에서 스레드가 굶어 죽을 수도 있습니다.
사용하여 주문을 보장 할 수 있습니다 재진입 락 (Java 5.0 이후) fair=true
옵션. (Lock lock = new ReentrantLock(true);
)
다른 팁
아니요 동기화 된 메소드에 대한 두 개의 호출이 순서대로 발생하는지 확신 할 수 없습니다. 주문은 지정되지 않고 구현에 따라 다릅니다.
이것은에 정의됩니다 17.1 자물쇠 JLS 섹션. 자물쇠에서 대기하는 스레드가 액세스 할 수있는 순서에 대해서는 아무 말도하지 않습니다.
각 스레드에서 특정 방법이 호출되는 순서에 의존 할 수 없습니다. 두 개의 스레드 만 있으면 예일 수 있습니다. 그러나 3 개의 스레드와 1 개의 스레드가 이미 획득 된 액세스가 있는지 상상해보십시오. 접근을 시도 할 때 다른 2 개의 스레드는 기다릴 것이며 그 중 하나는 액세스를 수여 할 수 있으며,이 방법을 호출하는 순서에 따라 다르지 않습니다. 따라서 주문에 의존하는 것은 제안되지 않습니다.
c) 요청을 직렬화하는 더 좋은 방법이 있습니까?
목록을 대기열로 사용하는 것은 우연히 사용 패턴이 다음과 같이 보입니까?
while (some condition) { synchronized(theList){ anItem = get and remove an element from theList } do some work with anItem }
그렇다면, 당신은 BlockingQueue
자체 잠금 체계를 사용하는 대신 인터페이스. 구현 (같은 ArrayBlockingQueue
) 공정성 등을위한 설정이 있습니다.
자체 강도를 정의하지 않는 한 항상 앱 서버 또는 엔진에 동기화됩니다.
예.
목록에 대한 액세스가 하나의 동기화 된 메소드를 통해이면 여러 스레드의 동시 요청이 직렬화됩니다.