[java] 정적 클래스 변수를 수정하지 않으면 동기화되지 않은 정적 메소드가 스레드 안전합니까?

난 당신이하는 정적 방법이 있다면 궁금 하지 동기화를하지만 않습니다 하지 정적 변수를 수정할 수는 스레드 안전? 메소드가 그 안에 로컬 변수를 작성하면 어떨까요? 예를 들어 다음 코드는 스레드로부터 안전합니까?

public static String[] makeStringArray( String a, String b ){
    return new String[]{ a, b };
}

따라서 두 개의 스레드가 연속적으로 동시에 호출하는 두 개의 스레드가 있으면 하나는 개 ( “그레이트 데인”및 “불독”)와 다른 하나는 고양이 ( “페르시아어”및 “샴”)와 함께 고양이와 개를 얻습니다. 같은 배열에서? 아니면 고양이와 개가 동시에 같은 방법으로 호출되지 않습니까?



답변

이 방법은 100 % 스레드 안전합니다 static. 그렇지 않은 경우에도 마찬가지 입니다. 스레드 안전성 문제는 스레드간에 데이터를 공유해야 할 때 발생합니다. 원 자성, 가시성 등을 관리해야합니다.

이 메소드는 스택에 상주 하고 힙의 불변 오브젝트에 대한 참조 대해서만 매개 변수 에서만 작동 합니다 . 스택은 본질적으로 스레드에 로컬 이므로 데이터 공유가 발생하지 않습니다.

변경 불가능한 객체 ( String이 경우)도 일단 생성되면 변경할 수없고 모든 스레드가 동일한 값을 볼 수 있기 때문에 스레드로부터 안전합니다. 반면에 방법이 수락 가능 Date하면 (변경 가능) 문제가있을 수 있습니다. 두 개의 스레드가 동일한 객체 인스턴스를 동시에 수정하여 경쟁 조건 및 가시성 문제를 일으킬 수 있습니다.


답변

메소드는 공유 상태가 변경 될 때만 스레드 안전하지 않을 수 있습니다. 정적인지 여부는 관련이 없습니다.


답변

이 기능은 완벽하게 스레드 안전합니다.

당신이 그것에 대해 생각한다면 … 이것이 다르다면 어떻게 될지 가정하십시오. 모든 일반적인 함수는 동기화되지 않으면 스레딩 문제가 발생하므로 JDK의 모든 API 함수는 잠재적으로 여러 스레드에 의해 호출 될 수 있으므로 동기화되어야합니다. 대부분의 경우 앱에서 일부 API를 사용하므로 멀티 스레드 앱은 사실상 불가능합니다.

이것은 생각하기에는 너무 우스운 일이므로, 당신만을 위해 : 문제가 발생할 수있는 분명한 이유가 있다면 메소드는 스레드 안전하지 않습니다. 내 기능에 여러 스레드가있는 경우 무엇을 생각하고 단계 디버거가 있고 첫 번째 단계를 차례로 진행 한 다음 두 번째 스레드는 아마도 두 번째 스레드는 아마도 두 번째 스레드는 무엇인지 생각하십시오. 문제가 있습니까? 하나를 찾으면 스레드 안전하지 않습니다.

또한 ConcurrentHashMap과 같이 명시된 경우를 제외하고 대부분의 Java 1.5 Collection 클래스는 스레드로부터 안전하지 않습니다.

그리고 이것에 대해 자세히 알고 싶다면 휘발성 키워드와 모든 부작용을 자세히 살펴보십시오. java.util.Concurrent에서 Semaphore () 및 Lock () 클래스와 그 친구를 살펴보십시오. 클래스 주위의 모든 API 문서를 읽으십시오. 배우고 만족시키는 것도 가치가 있습니다.

이 정교하게 답변 해 주셔서 죄송합니다.


답변

static스레드간에 공유되는 정적 데이터를 수정하려면 동기화 된 정적 메소드와 함께 키워드를 사용하십시오 . static키워드를 사용하면 작성된 모든 스레드가 단일 버전의 메소드에 대해 경쟁합니다.

volatile동기화 된 인스턴스 메소드와 함께 키워드를 사용하면 각 스레드에 고유 한 공유 데이터 사본이 있으며 스레드간에 읽기 / 쓰기가 누출되지 않습니다.


답변

변경 불가능한 문자열 객체는 위의 스레드 안전 시나리오의 또 다른 이유입니다. 대신 변경 가능한 객체 (예 : makeMutableArray ..)를 사용하면 스레드 안전성이 확실히 손상됩니다.


답변