문제

다음에 대한 이해는 무엇입니까?
나는 겪었다 이것 그렇게 게시하지만 여전히 그것을 조립하기 위해 손실됩니다.

코드 1 :

synchronized(this){ 
// some code
}

Code2 :

Object lock = new Object();

synchronized(lock){
// some code
}

어린이에게 설명하는 것처럼 동기화 된 튜토리얼 또는 동기화 된 링크가 있습니까?

도움이 되었습니까?

해결책

이미 주어진 훌륭한 답변에서 언급되지 않은 한 가지는 Code1과 Code2의 차이가 있다는 것입니다. Code1에서 동기화는 코드가 발견되는 객체의 인스턴스에 있으며 Code2에서는 객체 내의 특정 잠금 객체에 있습니다.

Enclosing 클래스에 동기화 된 블록 두 개만 있으면 기능의 둘 사이의 차이점이지만 이것을 고려하십시오.

class CodeOneClass {
  ...
  synchronized(this) {   // or merely "synchronized" - it defaults to this
      first protected code block
  }
  ...
  synchronized(this) {   
      second protected code block
  }
...
}

class CodeTwoClass {
  ...
  Object lock1 = new Object();
  synchronized(lock1) {   
      first protected code block
  }
  ...
  Object lock2 = new Object();
  synchronized(lock2) {   
      second protected code block
  }
...
}

두 스레드가 동일한 인스턴스의 CodeOneClass를 사용하려고하면 그 중 하나만 두 개의 보호 코드 블록 중 하나입니다 동시에.

그러나 두 번째 관용구를 사용하면 한 스레드가 첫 번째 보호 블록에 있고 다른 스레드가 다른 스레드에있는 것이 안전하다고 말할 수있는 유연성이 있습니다. 잠금 장치가 동일하다면 (동일한 잠금 객체에서 동기화) 동작은 첫 번째 것입니다.

다른 차이점이 있습니다. 일부 작가들은 문제를 지적하기 시작했습니다 동기화 (this) - 여기에 다른 게시물을 알려 드리겠습니다.자바에서 동기화 (이것)을 피하십시오.

나는 그것을 읽는 것이 좋습니다.

다른 팁

기본적으로 Java의 모든 객체와 관련된 "잠금"이 있습니다.

스레드가 동기화 된 (무언가) 호출에 도달하면 계속하기 전에 무언가의 잠금을 얻어야합니다. 한 번에 하나의 스레드 만 허용하여 객체의 상태를 수정하려면 가장 분명한 것은 해당 객체의 잠금을 동기화하는 것입니다. 다른 방법을 병렬로 호출 할 수 있으면 다른 자물쇠가 필요합니다.

동기화 된 (this)를 쓰거나 단순히 동기화 된 경우 스레드는 현재 객체와 관련된 잠금을 가져와야합니다 (메소드가 호출).

Java 5.0이므로 동시 패키지가 적절하게 제공됩니다. 자물쇠 동기화 대신 사용할 수 있습니다.

내에 코드를 넣습니다 synchronized 블록은 본질적으로 "이 코드가 실행되기 시작하면이 객체를 사용해야하는 다른 코드는 동시에 실행할 수 없습니다."

따라서 스레드 #2가 코드를 실행하는 경우 code2 블록, synchronized(lock) 코드 다른 모든 스레드를 효과적으로 검토하여 다른 사람이 "동기화 된"코드를 lock 현재 객체. 스레드 #1은 확실히 실행 중입니다 약간 코드는 동시에 코드이지만 완전히 관련이없는 코드 일 수 있습니다. 그렇다면 스레드 #2가 실행을 시작하는 것이 안전합니다.some code" 물건.

한편, 스레드 #1이 synchronized(this) 블록, 또한 다른 스레드가 사용 중인지 멈춰야합니다. this. 만약에 this 같은 대상입니다 lock, 문제가있다. 우리는 하나의 스레드만이 동시에 해당 객체 (동기화 된 블록)를 사용할 수 있다고 들었습니다. 그러나 스레드 #2는 이미 그것을 사용하고 있습니다. 스레드 #1은 그냥 기다려야합니다 ... 그리고 기다렸다가 ... 기다려 ... 결국 스레드 #2가 끝날 때까지 기다립니다. 그런 다음 우리는 진행할 수 있습니다.

최종 결과는 단 하나입니다 synchronized 블록은 한 번에 실행할 수 있습니다 (물론 특정 물체와 함께).

당신이 있다고 가정합니다 Account 메소드가있는 개체 :

void debit(long debitAmount, Account beneficiary) throws InsufficientFundsException
{
   if (accountBalance >= debitAmount) {
      accountBalance -= debitAmount;
      beneficiary.credit(debitAmount);
   }
   else {
      throw new InsufficientFundsException();
   }
}

이제 잔액이 100 유로의 계정을 가지고 있다고 가정하고 70 유로의 차변을 두 번 시도합니다. 두 차감이 동시에 발생하면 경쟁 조건 이와 같이:

  • 첫 번째 차변 점검 계정 잔액 : 100> = 70이므로 성공합니다.
  • 두 번째 직불 검사 계정 잔액 : 100> = 70이므로 성공합니다.
  • 첫 번째 직불 실행; 계정 잔액은 30이됩니다
  • 두 번째 직불 실행; 계정 잔액은 -40이됩니다. 허용되지 않아야합니다

우리는이 무서운 상황을 Account 물체의 자물쇠 :

void debit(long debitAmount, Account beneficiary) throws InsufficientFundsException
{
   synchronized (this) {
      if (accountBalance >= debitAmount) {
         accountBalance -= debitAmount;
         beneficiary.credit(debitAmount);
      }
      else {
         throw new InsufficientFundsException();
      }
   }
}

이는 계정 잔액에 대한 다른 테스트로 계정 잔액 및 차변 테스트를 중단 할 수 없도록합니다.

그만큼 Sun Java 튜토리얼 동시성 및 잠금에 대한 정보를 시작하기에 좋은 곳입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top