2012-06-25 5 views
10

Java 동기화와 관련하여 의문의 여지가 있습니다. 내 클래스에 3 개의 동기화 된 메서드가 있고 스레드가 하나의 동기화 된 메서드에서 잠금을 획득하는지 알고 싶습니다. 다른 두 메서드는 잠겨 있습니까? 나는 다음 질문에 혼란스러워서이 질문을하고있다.Java에서 동기화가 어떻게 작동합니까?

스레드가 개체의 동기화 된 메서드 내에있는 동안이 동기화 된 메서드 또는 개체의 다른 동기화 된 메서드를 실행하려는 다른 모든 스레드가 대기해야합니다. 이 제한은 이미 잠금이 있고 스레드의 동기화 된 메소드를 실행중인 스레드에는 적용되지 않습니다. 이러한 메서드는 차단되지 않고 개체의 다른 동기화 된 메서드를 호출 할 수 있습니다. 객체의 비동기 메소드는 물론 모든 스레드가 언제든지 호출 할 수 있습니다.

+1

그 진술의 근원은 무엇이며 혼동은 무엇입니까? 당신은 그것을 이해하는 것 같습니다. 동기화 된 하나의 메소드를 다른 메소드에서 액세스 할 때 교착 상태에주의하십시오. – Sridhar

+0

Re : "다른 두 개가 잠길 것입니다." 이미 잠금을 가지고있는 현재 실행중인 스레드는 동일한 객체에서 다른 동기화 된 메소드를 호출 할 수 없지만 다른 스레드는 모두 차단됩니다 (즉, 잠금이 주어질 때까지 기다려야합니다). 맥스는 객체 자체 (즉, this) 또는 다른 객체 변수를 완전히 잠그고 있는지에 대한 좋은 대답을 가지고 있습니다. – Brad

답변

7

java의 동기화는 특정 개체에서 모니터를 가져와 수행됩니다. 따라서, 당신이 할 경우 : someVariable가 수정되지 않은 상태에서

class TestClass { 
    SomeClass someVariable; 

    public void myMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 

    public void myOtherMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 
} 

그리고 두 블록이 언제든지이 개 다른 스레드의 실행에 의해 보호됩니다. 기본적으로 두 블록은 변수 someVariable에 대해 동기화됩니다.

synchronized을 메서드에 넣으면 기본적으로 synchronized (this)과 같은 의미이며, 즉이 메서드가 실행되는 개체의 동기화입니다.

즉 :

public synchronized void myMethod() { 
    ... 
} 

는 의미와 동일 :

따라서
public void myMethod() { 
    synchronized (this) { 
     ... 
    } 
} 

, 귀하의 질문에 대답하기 - 예, 스레드가 동시에 다른 스레드에서 그 메소드를 호출 할 수 없습니다, 둘 다 동일한 모니터에 대한 참조를 보유하고 있으므로 this 오브젝트의 모니터.

+0

최대, 마지막 문장에서 "잠금"이라는 용어는 오해의 소지가 있습니다. 나는 당신이 "... 같은 모니터에 대한 참고 자료를 가지고 있기 때문에 ..."라고 말하기를 생각합니다. 두 개의 스레드는 동시에 같은 모니터의 잠금을 가질 수 없습니다. – Brad

+0

@Brad 정정을 보내 주셔서 감사합니다. – bezmax

+0

첫 번째 단락에서 전달한 것을 얻지 못하면 간단한 용어를 설명해주십시오. – userab

1

예.
동기화 된 메서드 스레드를 실행하려면 개체에 대한 잠금을 가져와야하며 한 번에 하나의 스레드 만 개체에 대한 잠금을 얻을 수 있습니다.

0

각 Java 객체 (클래스 인스턴스)에는 뮤텍스 객체가 있습니다. 메서드 앞의 synchronized 키워드는 실행중인 스레드가 해당 개체에 대한 뮤텍스에 대한 잠금을 가져와야 함을 의미합니다. 사실,

public synchronized doSomething(){ 
    ... 
} 

정확히이 같은인가 :
public doSomething(){ 
    synchronized(this){ 
     ... 
    } 
} 

는 그래서 그래, 단지 클래스 인스턴스 당 동기화 방법을 실행하는 하나 개의 스레드가있을 것입니다.

수정 사항을 보호하고 동시 읽기에 문제가 없으므로 때때로이 옵션이 최적이 될 수 없다는 점에 유의하십시오.이 경우 동기화 된 키워드 대신 ReadWriteLock을 살펴볼 수 있습니다.

-1

혼란 스러울 지 모르겠지만 자물쇠를 채우는 동안 다른 스레드가 그것을 획득하지 못하도록 차단하고 클래스의 모든 비 정적 동기화 된 메소드가 같은 객체에서 동기화되므로 응답 귀하의 질문에 '예', 나는 당신을 올바르게 이해했다고 가정합니다. 나는 다른 어떤 의미와 함께 "동기화 된"것이 무엇을 의미하는지, 또 어떤 의미가 있는지를 모른다.

0

음, 객체 당 하나의 잠금 만 있습니다. 모든 동기 메소드는이 락에 의해 락됩니다. 따라서 어느 스레드가 한 번에 잠금을 획득하든 모든 동기화 된 메소드를 통과 할 수있는 권한이 있습니다. 그러나 잠금을 기다리는 스레드는 잠금을 얻을 때까지 메소드를 동기화 할 수 없습니다.

그래서 한 번에 오직 스레드 규칙 만이 동기화 된 방법을 입력하기 위해 대기해야하며, 지배 스레드가 해당 방법을 실행하고 있는지 여부는 중요하지 않습니다.

0

예. 잠금을 획득 한 스레드를 제외하고 모든 스레드는 동기화가 동기화 된 세 가지 방법 중 하나를 실행할 수 있도록 다시 해제 될 때까지 대기해야합니다.

정상적인 방법

synchronized(this) { 
    // method body 
} 
0

그것은 사실이며 이런 식으로하지에 둘러싸여으로 동기화 방법은 동일 기억하십시오. 해당 개체의 데이터를 일관되게 유지하는 것이 필요합니다.

이 유효성 검사가없고 변수 x가 2 개의 다른 동기화 된 메소드 xxx() 및 yyy()에 의해 조작되고 있다고 가정합니다.

그래서 스레드 A가 x = 5를 조작하는 메소드 xxx()를 잠그고 두 번째 스레드 B가 메소드 yyy()를 잠그고 x = -5를 조작하면 xxx() 메소드 끝에서 스레드 A가 x = 5를 기대하지만 x = 0을 얻습니다.

왜 이런 방식으로 구현 되었습니까?

0

클래스에 동기화 메소드가 4 개있는 경우 한 번에 하나의 스레드 만 해당 메소드에 액세스 할 수 있습니다. 여기에 의심의 여지가 없다고 생각합니다. 각 스레드는 단일 클래스 인스턴스에 대해 한 번에 diff 동기화 된 메서드에 액세스 할 수 있습니다. 내 대답은 아니오 야. 한 번에 하나의 스레드 만 동기화 된 메소드에 액세스 할 수 있습니다.

관련 문제