2010-05-11 2 views
4

개체의 공용 메서드가 전달 된 매개 변수와 로컬 변수 만 사용하는 경우메서드가 객체의 필드를 사용하지 않으면 스레드로부터 안전합니까?

스레드 안전하다고 말할 수 있습니까?

+1

모든 매개 변수를 변경할 수 있습니까? –

+0

@DaDaDom 그들은 'final'이라고 표시되어 있지 않지만 메서드 본문 내에서 변경되지 않습니다. 최종 결정을해야한다고 생각하십니까? – EugeneP

+0

부작용이없고 메서드가 정적 로컬 변수를 사용하지 않는 경우 –

답변

9

실제로는 pure function라고하는 A는 실제로는 안전하지만, 부작용이 전혀없는 경우에만 (즉, 매개 변수가 변경된 매개 변수를 통해 전달 된 경우) 가능합니다.

1

예, 스레드로부터 안전합니다. 다른 메소드의 호출을 방해 할 수 없습니다. (다른 불쾌한 부작용이없는 한)

이 방법의 지침을 인터리빙하고 다른 방법의 지침도 괜찮습니다.

3

로컬 memeber 변수가 수정되지 않고 전달 된 매개 변수의 상태가 변경되지 않으면 (즉, 해당 매개 변수의 메소드를 통해) 스레드로부터 안전합니다.

또한 전달 된 매개 변수가 객체 인 경우 최종 매개 변수를 쓰는 것은 스레드 안전성을 보장하지 않습니다.

public class Foo{ 
    private int count = 1; 
    public void incrementFoo(){ 
     count += 1; 
    } 
    public int getFoo(){ 
     return count; 
    } 
} 

private int multiplier = 5; 
//Not safe 
public static int calculateFoo(final Foo myFoo){ 
    //you can still do this, even if myFoo is final 
    myFoo.incrementFoo(); 
    return myFoo.getFoo() * multiplier; 
} 
+1

로컬 변수를 수정하지 않아도되는 이유는 없습니다. –

+0

이제 생각해 보면 질문을 놓친 것 같습니다. 로컬 변수는 메소드가 호출되는 클래스의 로컬 변수로 생각했습니다. 아마 무엇을 의미 했을까? 메소드의 범위에 대한 지역 변수. foo 예제에서는 "multiplier"를 로컬로 생각했습니다. –

+1

일반적으로 'multiplier'는 멤버 변수라고합니다. 로컬 변수는 사용자가 언급 한대로 실행중인 현재 메소드의 범위에만 있습니다. – laz

1

이 달려있다. 쉽게 스레드로부터 안전하지 않을 수있는 방법이 있습니다.

먼저 메서드에 전달 된 인수가 스레드로부터 안전하지 않고 메서드가 적절한 동기화없이 다중 스레드 방식으로 스레드를 사용하면 스레드로부터 안전하지 않습니다. 예를 들어,

// HashMap is not thread safe 
public void foo(String key, HashMap<String,String> map) { 
    String value = map.get(key); 
    if (value == null) { 
    map.put(key, "new value"); 
    } 
} 

또 다른 가능성은 메서드 내에서 생성 된 개체가 메서드를 이스케이프하는지 여부입니다. 다음 고려 :

이 큐에 대기하고지도 객체를 사용하기 시작하는 다른 스레드가있는 경우
public void foo() { 
    Map map = ...; // create and populate the map 
    ListenerQueue.getQueue().add(map); // there are listener threads waiting on this queue 
    // do some other work 
} 

, 다음지도 객체 탈출, 같은 스레드 안전 문제로 될 수있다.

+0

이러한 모든 것은 위의 대답에서 "부작용"으로 간주 될 수 있습니다. 이들은 몇 가지 구체적인 예입니다. 로컬 메소드 호출은 스레드 안전성 측면에서 다루기는 쉽지만 확실하지는 않다는 것을 설명합니다. – sjlee

관련 문제