2012-11-27 2 views
0

좋아, 스레드 안전 구현이있는 Java Math 클래스가 있다고 가정 해 보겠습니다. 스레드 A는 이제 SetValue (1)을 실행하고 Math 클래스를 잠급니다. 스레드 B가 GetValue()로 동시에 액세스하려고하면 어떻게됩니까? 잠금 해제 또는 메서드 요청이 경고 또는 예외없이 직접 종료 될 때까지 기다릴 것입니까?첫 번째 스레드가 클래스를 잠글 때 두 번째 스레드에 어떤 일이 일어나는가

public class Math { 
     private static int value = 0; 

     public synchronized static void setValue(int value) { 
      Math.value = value; 
     } 

     public synchronized static int getValue() { 
      return value; 
     } 
} 
+5

첫째, 정적 메서드에서 "this"를 사용할 수 없습니다. – Juvanis

+0

죄송합니다. 저는 순수한 글쓰기로 간단한 예를 만들었습니다. 나는 클래스가 잠겨있을 때 다음 스레드가 어떻게 동작 할 것인지를 확인하고자한다. – lannyboy

+0

여기서 주목해야 할 몇 가지 사항은 다음과 같습니다. 1) 'int'에 할당/읽기는 모든 Java 구현에서 원자 연산이므로 'synchronized'는 이와 관련하여 도움이되지 않습니다. 2) 클래스가 동기화되어 있어도 경쟁 조건을 결코 막지 않습니다. –

답변

1

첫 번째 스레드가 잠금을 해제 할 때까지 필요한 경우 영원히 기다립니다.

+0

답변 주셔서 감사합니다 :) 그럼 내 싱글 톤 스레드 안전 웹 디자인에 적용됩니다 :) – lannyboy

+0

예. 하지만 AtomicInteger를 사용하지 않는 이유는 무엇입니까? –

+0

아니요, 이것은 내 기원 디자인이 아니며 샘플 용으로 원시 형식으로 입력했습니다. 클래스가 잠길 때 다음 스레드 동작을 확인하려고합니다. – lannyboy

3

예 두 번째 스레드는 잠금을 다시 사용할 수있을 때까지 대기합니다. 잠금 장치를 사용할 수 없게되면 생체 문제가 발생하고 두 번째 스레드가 중단됩니다.

JLS 17.1 이것은 더욱 상세하게 설명된다

동기화 된 방법은 자동 호출 잠금 동작을 수행한다; 잠금 동작이 성공적으로 완료 될 때까지 본체가 실행되지 않습니다. [...] 메서드 본문의 실행이 정상적으로 또는 갑자기 완료되면 같은 모니터에서 자동으로 잠금 해제 작업이 수행됩니다. 또한

참고 :

자바 프로그래밍 언어는 방지하지 않고 교착 상태의 감지를 필요로 둘. 쓰레드가 (직접적으로 또는 간접적으로) 다중 객체를 잠그는 프로그램은 교착 상태 회피를위한 전통적인 기술을 사용하여 필요하다면 교착 상태가 아닌 더 높은 수준의 잠금 기본을 작성해야합니다.

1

Thread는 대기 큐에 추가하고, 그것은 SetValue 방법을 실행 Thread A까지이 남아 있고 잠금을 해제하지 않습니다.

Thread A이 잠금을 해제하자마자 Thread B에 알리고 그 후에 계속할 수 있습니다.

또한 Thread ASetValue 메서드에 들어갈 때 해당 클래스의 모든 동기화 된 메서드에 대한 잠금을 가져옵니다. 따라서 Thread B은 을 실행할 수 없습니다. Thread A이 완료되면 SetValue 메서드가 실행되고 점차 잠금이 해제됩니다.

그리고 잠시 잠금을 해제하면 Thread B이 즉시 GetValue 메서드 실행을 시작할 것이라고 보장 할 수 없습니다. 이 스레드 B에


P.S을 자원을 할당 않을 때 그것은 모두의 CPU에 따라 달라집니다 : - 자바 코드에서 이름 지정 규칙을 따르십시오. 메소드 이름은 lowercase 문자로 시작해야합니다. 따라서 방법은 getValuesetValue이어야합니다.

+0

짧고 간결한 대답. +1. – Juvanis

+0

귀하의 세부 설명을 주셔서 감사합니다 :) – lannyboy

+0

@ lannyboy .. 당신은 환영합니다 :) –

1

작은 그림 :

public class Math { 

private static int value = 0; 

public synchronized static void SetValue(int _value) throws InterruptedException { 

    Thread.sleep(1000L); 
    value = _value; 
} 

public synchronized static int GetValue() { 

    return value; 
} 

public static void main(String[] args) { 

    new Thread(new Runnable() { 

    @Override 
    public void run() { 

    try { 
    SetValue(-100); 
    } catch (InterruptedException e) { 
    // ignore 
    } 
    } 
    }).start(); 

    new Thread(new Runnable() { 

    @Override 
    public void run() { 

    System.out.println("GetValue() = " + GetValue()); 
    } 
    }).start(); 
} 
} 

출력된다 :

GetValue() = -100 

번째 스레드는 초 자와 설정 한 후에 일어나 처음 기다릴가는 것을 의미 value ~ 100.

+1

당신의 설명을 주셔서 감사합니다 :) – lannyboy

관련 문제