java 동기화 대 잠금





5 Answers

나는 이것들 중 어느 것이 실제로 더 낫고 왜 그런지 궁금하다.

LockCondition (및 다른 새로운 concurrent 클래스)이 도구 상자의 도구 일 뿐이라는 것을 알았습니다. 나는 오래된 클로 해머 ( synchronized 키워드)로 필요한 모든 것을 할 수 있었지만, 어떤 상황에서는 사용하기가 어색했다. 고무 망치, 볼 - 핑 망치, 프라이 바 (prybar), 일부 못 펀치 (nunch punch) 등 도구 상자에 더 많은 도구를 추가하면 어색한 상황이 훨씬 더 간단 해졌습니다. 그러나 , 내 오래된 발톱 망치는 여전히 사용의 점유율을보고있다.

나는 하나가 다른 것보다 "더"훌륭하다고 생각하지 않지만, 오히려 각각은 다른 문제에 더 잘 맞는다. 간단히 말해서 synchronized 의 단순한 모델과 범위 지향적 특성은 코드의 버그로부터 나를 보호하는 데 도움이되지만보다 복잡한 시나리오에서는 이러한 이점이 때때로 방해가됩니다. 동시 패키지가 작성된이보다 복잡한 시나리오는 해결에 도움이됩니다. 그러나이 고급 구성을 사용하면 코드에서보다 명확하고 신중한 관리가 필요합니다.

===

나는 JavaDocLocksynchronized 의 차이점을 설명하는 훌륭한 역할을한다고 생각한다. (강조점은 내 것이다.)

잠금 구현은 동기화 된 메서드 및 문을 사용하여 얻을 수있는 것보다 더 광범위한 잠금 작업을 제공합니다. 그것들은, 보다 유연한 구조화를 가능하게 해 , 상당히 다른 속성을 가질 수가있어 관련의 복수의 Condition 객체를 지원할 가능성이 있습니다 .

...

동기화 된 메소드 또는 명령문을 사용하면 모든 객체와 관련된 암시 적 모니터 잠금에 대한 액세스가 제공되지만 모든 잠금 획득 및 해제가 블록 구조로 수행되도록합니다 . 다중 잠금획득 한 경우 반대 순서로 해제해야 하며 모든 잠금은 획득 된 동일한 어휘 범위에서 해제되어야합니다 .

동기화 된 메소드 및 명령문의 범위 지정 메커니즘은 모니터 잠금으로 프로그래밍하는 것이 훨씬 쉬우 며 잠금관련된 많은 일반적인 프로그래밍 오류를 방지 하는 데 도움 이되지만보다 유연한 방법으로 잠금을 사용해야하는 경우가 있습니다. 예를 들어, 동시에 액세스되는 데이터 구조를 탐색하기위한 일부 알고리즘 * 은 노드 A의 잠금을 획득 한 다음 노드 B의 잠금을 획득 한 다음 A를 해제하고 C를 획득하는 "수동 전달"또는 "체인 잠금" 그런 다음 B를 놓고 D를 얻는다. Lock 인터페이스의 구현은 다양한 범위 에서 잠금을 획득하고 해제 할 수 있도록 허용하고 여러 잠금을 임의 순서로 획득하고 해제 할 수 있도록하여 이러한 기술의 사용을 가능하게합니다.

이러한 유연성 증대로 인해 추가적인 책임이 따릅니다 . 블록 구조 잠금없으면 동기화 된 메소드 및 명령문에서 발생하는 잠금 자동 해제가 제거됩니다 . 대부분의 경우 다음 관용구를 사용해야합니다.

...

다른 범위에서 잠금 및 잠금 해제가 발생 하면 잠금 이 실행되는 동안 실행되는 모든 코드가 try-finally 또는 try-catch보호되어 필요한 경우 잠금이 해제되는지 확인해야합니다 .

잠금 구현은 잠금 을 획득하기 위한 비 차단 시도 (tryLock ()), 중단 될 수있는 잠금획득 하려는 시도 (lockInterruptibly () 및 획득 시도)를 제공하여 동기화 된 메소드 및 명령문을 사용하는 보다 추가 기능 을 제공합니다 타임 아웃 할 수있는 락 (tryLock (long, TimeUnit))

...

java multithreading concurrency synchronization java.util.concurrent

java.util.concurrent API는 Lock 이라는 클래스를 제공합니다. Lock 은 중요한 리소스에 액세스하기 위해 기본적으로 컨트롤을 직렬화합니다. park()unpark() 와 같은 메소드를 제공합니다.

synchronized 키워드를 사용하고 wait()notify() notifyAll() 메소드를 사용할 수있는 경우 비슷한 작업을 수행 할 수 있습니다.

나는 이것들 중 어느 것이 실제로 더 낫고 왜 그런지 궁금하다.




synchronized 또는 java.util.concurrent.Lock 을 사용하려는 이유에는 4 가지 주요 요소가 있습니다.

참고 : 동기화 된 잠금은 내재 된 잠금을 말할 때의 의미입니다.

  1. 자바 5가 ReentrantLocks를 가지고 나왔을 때, 그들은 intrinsic locking 이후 주목할만한 처리량 차이를 가지고 있음이 판명되었다. 더 빠른 잠금 장치를 찾고 1.5를 실행중인 경우 jucReentrantLock을 고려하십시오. Java 6의 내장 잠금은 이제 비교할 수 있습니다.

  2. jucLock에는 잠금 메커니즘이 다릅니다. 잠금 인터럽트 가능 - 잠금 스레드가 인터럽트 될 때까지 잠금을 시도합니다. timed lock - 일정 시간 동안 잠금을 시도하고 성공하지 못하면 포기합니다. tryLock - 다른 스레드가 잠금을 유지하고 있으면 잠금을 시도합니다. 이 모든 것은 간단한 자물쇠에서 제외됩니다. 고유 잠금은 단순 잠금 만 제공합니다.

  3. 스타일. 1과 2가 모두 나 자신을 포함하여 대부분의 사람들과 관련된 범주에 속하지 않으면 본질적인 잠금 semenatics가 읽기 쉽고 jucLock 잠금은 덜 자세하게 나타납니다.
  4. 복수 조건. 잠그는 객체는 알림 만 받고 하나의 사례 만 대기합니다. Lock의 newCondition 메소드는 단일 Lock이 기다리거나 신호 할 여러 가지 이유를 가질 수있게합니다. 나는 실제로 실제로이 기능이 필요하지만, 필요한 사람들에게는 좋은 기능입니다.



Brian Goetz의 "Java Concurrency In Practice"13.3 절. "... ReentrantLock과 마찬가지로 내장 된 잠금은 결정론적인 공정성 보장을 제공하지 않지만 대부분의 잠금 구현에 대한 통계적 공정성 보장은 거의 모든 상황에서 충분합니다."




Lock은 프로그래머의 삶을 편하게 해줍니다. 자물쇠로 쉽게 얻을 수있는 몇 가지 상황이 있습니다.

  1. 하나의 메소드를 잠그고 다른 메소드에서 잠금을 해제하십시오.
  2. 두 개의 다른 코드에서 작업하는 두 개의 스레드가 있지만 첫 번째 스레드는 다른 스레드가 동시에 작동하는 동안 더 진행하기 전에 특정 코드를 완료하기 위해 두 번째 스레드에 대한 종속성이 있습니다. 공유 잠금은이 문제를 아주 쉽게 해결할 수 있습니다.
  3. 모니터 구현. 예를 들어 put 및 get 메소드가 여러 스레드에서 실행되는 단순 대기열. 그러나, 당신은 동일한 방법을 서로 겹치기를 원하지 않겠습니까? 또한 넣기와 가져 오는 방법이 중복 될 수는 없습니다. 그런 경우에는 사설 잠금 장치가있어서 인생을 훨씬 쉽게 해줍니다.

동안, 자물쇠 및 조건은 동기화에 빌드됩니다. 그래서 확실히 그 목표를 달성 할 수 있습니다. 그러나 그것은 당신의 삶을 어렵게 만들고 실제 문제를 푸는 데에서 벗어날 수 있습니다.




블록 잠금 및 동기화는 모두 동일한 용도로 사용되지만 사용 용도에 따라 다릅니다. 아래 부분을 고려하십시오.

void randomFunction(){
.
.
.
synchronize(this){
//do some functionality
}

.
.
.
synchronize(this)
{
// do some functionality
}


} // end of randomFunction

위의 경우 스레드가 동기화 블록에 들어가면 다른 블록도 잠 깁니다. 동일한 객체에 동기화 블록이 여러 개 있으면 모든 블록이 잠겨 있습니다. 이러한 상황에서 java.util.concurrent.Lock은 블록의 원치 않는 잠금을 방지하는 데 사용할 수 있습니다




Related