2014-09-16 4 views
3

여러 스레드에서 액세스되는 상수가있는 파일을 만들고 싶습니다. 이것을 위해서 많은 public static final int 클래스를 갖는 것은 안전한 구현입니까?public static final int thread가 안전합니까?

+0

일반적으로 (실수를하지 않는 한) 클래스는 완전히 초기화되기 전에 초기화됩니다. 정적 초기화는 사용자의 명시적인 동기화없이 다른 스레드에서 볼 수 있습니다. –

답변

8

예, 스레드로부터 안전합니다. 모든 static final 변수는 클래스 초기화 후에 초기화되도록 보장됩니다. 따라서 코드에 static final 변수가 포함 된 클래스가 사용되면 requirement of the JVMS으로 항상 완전히 초기화됩니다 (즉, 값이 설정 됨).

프리미티브가 int 인 경우이 조건이 더 엄격합니다. static final 프리미티브 변수 (String과 동일)는 Java 컴파일러 javac에 의해 인라인 화되는 이른바 compile-time constant입니다. 유일한 요구 사항은 Java 컴파일러에서 값을 계산할 수 있다는 것입니다. 즉, 값이 비정상적으로 평가 된 결과가 아니어야합니다. 상수를으로 정의하고 싶다고 쓰고 있으므로,이 것은 사용 사례에 적용되지 않는다고 가정합니다. 따라서 상수 값은 비 프리미티브 유형의 문제 인 가상의 반사를 통해 변경되는 static final 변수의 비 스레드 안전성의 경우를 잘라내는 액세스 위치에 직접 복사됩니다.

또한 이러한 변수를 사용하는 것은 좋은 아이디어입니다. 이른바 magic numbers을 사용하지 않기 때문입니다.

+1

'static final'은 자동적으로 필드 * 컴파일시의 상수 *를 만들지 않습니다. 그것은 우리가 초기화 한 방법에 달려있다. (파일에서 데이터를 읽는 메소드의 결과라면 런타임에 값이 설정되어 컴파일러가 그것에 대해 알 수 없다는 것을 의미한다.) – Pshemo

+0

맞습니다. 제 대답에 제약 조건을 추가했습니다. –

3

예, 안전합니다.

값이 변경되지 않으므로 경쟁 조건이 발생할 위험이 없습니다. Java는 값을 사용하려고 시도하기 전에 값이 초기화된다는 것을 보장합니다.

다른 이유 (디자인의 명료성 등)가 가장 적합한 아키텍처인지 여부는 또 다른 질문입니다.

3

예, 100 % 안전합니다. 그것은 최종적인 것이므로 아무도 그것을 변경할 수 없습니다. 모든 스레드는 독자로만 액세스해야하며 읽기 전용 경합은 없습니다. 그 final 만드는 프리미티브 들어

+0

'final' 변수는 리플렉션 (또는 JVM에 의해'final' 변수가 강제되지 않기 때문에 코드 생성)을 사용하여 쉽게 변경 될 수 있습니다. –

1

는 그들 (방법의 결과로서 직접적으로 초기화되지 경우) 및 int프리미티브 인 시간 상수 컴파일한다. 따라서 final int을 변경할 수 없으므로이므로 스레드 안전이됩니다.

+0

"* 프리미티브 *의 경우,"final "로 설정하면 시정 수를 컴파일합니다 *" 거의 그곳에 있지만 이야기의 끝이 아닙니다. 올바른 선언 옆에 * 컴파일 시간 상수 *를 만들려면 적절한 초기화가 필요합니다. 이 경우에는 값을 직접 입력해야합니다. 예를 들어 파일에서 읽는 일부 메서드의 결과 (런타임시 컴파일러가 알 수 없음을 의미)가 발생하지 않습니다. – Pshemo

+0

"메소드/표현식 결과가 아닌"표현식은 다른 * 컴파일 시간 상수 *를 기반으로하면 OK입니다. 컴파일러는'1 + 2 + 3'을'6'으로 변경하고''foo '+'bar''는''foobar ''로 컴파일됩니다. – Pshemo

+0

@Pshemo -하지만 String a = "a"; 문자열 b = "b"; String s = a + b는 a와 b가 모두 최종 인 경우에만 컴파일 타임에 결정됩니다. 나는이 예를 고려하고 있었다. – TheLostMind

관련 문제