2011-11-13 3 views
2

Java String 클래스를 읽을 수 없으며 스레드로부터 안전하지만 String에 대한 참조 할당이 스레드로부터 안전한지 여부에 대해 여전히 혼란 스럽습니다.Java에서 문자열을 안전하게 설정/가져 오는 방법은 무엇입니까?

첫 번째 질문 : 스레드 B는 코드가 스레드 안전 따르고, Foo.getString() 호출하는 동안 스레드 A가 Foo.setString()를 호출하면?

Class Foo { 
    String aString; 
    public String getString() { 
     return aString; 
    } 
    public void setString(s) { 
     aString = s; 
    } 
} 

두 번째 질문 : 위의 코드는 스레드 금고, ReentrantLock와를 사용하여, 어떻게이 Foo.getString() 메소드를 작성하지 않은 경우?

Class Foo { 
    String aString; 
    ReentrantLock aLock; 
    public String getString() { 
     aLock.lock(); 
     return aString; 
     aLock.unlock(); // This line will be unreachable. How to fix?? 
    } 
    public void setString(s) { 
     aLock.lock(); 
     aString = s; 
     aLock.unlock(); 
    } 
} 

tryLock (제한 시간) 기능을 사용해야하므로 ReentrantLock을 사용해야합니다.

+0

내 질문에 모두 답하면 답변을 수락합니다. 감사. – Lee

답변

2

질문 1 : 스레드 안전성의 의미에 따라 달라질 수 있습니다. Eric Lippert wrote a very good blog post about it here ... aString을 volatile로 선언하면 다른 스레드의 모든 읽기가 정확함을 보증하게됩니다.

질문 2 : synchronized 키워드

public String getString() { 
    try {   
    aLock.lock(); 
    return aString; 
    } finally { 
    aLock.unlock(); 
    } 
} 

public void setString(s) { 
    try {   
    aLock.lock(); 
    aString = s; 
    } finally { 
    aLock.unlock(); 
    } 
} 
+0

제 첫 질문에 대해서 더 많이 알고 싶습니다. – Lee

+0

@Lee 업데이트를 참조하십시오. –

1

사용 :

public synchronized String getString() { 
     return aString; 
    } 

    public synchronized void setString(s) { 
     aString = s; 
    } 
+0

내 경우에는 tryLock (제한 시간) 기능을 사용해야하므로 ReentrantLock을 사용해야합니다. – Lee

+0

오케이, 눈치 채지 못했습니다. 따라서 다른 포스터가 제안한대로 finally 블록에서 잠금 해제하는 것이 좋습니다. – aleroot

+0

왜 tryLock을 사용해야합니까? 이 숙제인가요? – James

2

aString 휘발성 만들기가 전부입니다

이 (가) 예를 들어, finally 블록에서 해제하는이 ... 마지막으로 구성하려고 사용 당신은이 경우에 필요하다. (즉, 쓰기 이후에 읽은 것은 항상 최신 값을 볼 것이다.) - 우리가 단지 execu이기 때문에 메소드를 동기화시키는 것은별로 유용하지 않다. 단일 문장을 사용하는 경우 - 두 경우 모두 더 많은 작업을 수행하려면 더 높은 수준의 동기화가 필요합니다 ("문자열이 XYZ이면 XYA를 지정하십시오"). 나는. 동기화 및 휘발성 모두 동일한 보장을 제공합니다 (클래스의 다른 위치에서 동기화를 사용하면 명백한 차이점 제외)

휘발성이 충분하고 성능이 뛰어나지 만 동기화가 잘되어 있습니다. 많은 경쟁 액세스가 있었다면 그렇지 않으면 상관 없습니다 - 동기화는 적어도 핫스팟상의 비 경합 액세스에 대해 매우 최적화되었습니다 (그러나 모든 현대 JVM에 대해 동일하다고 가정합니다).