단일 모드 에 대한 약간의 생각
간단 하지만 고성능 과 스 레 드 안전 을 얻 는 사례 는 쉽 지 않다.
가장 간단 하고 성숙 한 사례 는 다음 과 같은 두 가지 가 있다.
1.
public static final Singleton INSTANCE=new Singleton();
정적 변 수 를 설명 할 때 예화 하 는 것 이다.이런 방법의 문 제 는 구조 적 인 파 라 메 터 를 전달 하여 동적 인 인 인 스 턴 스 를 만 들 수 없다 는 것 이다.
2.
public static synchronized Singleton getInstance(){...}
방법 적 으로 동기 화 하 는 것 이다.이런 방법의 문 제 는 항상 동기 화 된 비용 이 있다 는 것 이다.
더 좋아 보 이 는 방법(하지만 문제 가 있다!)예:
Double-checked synchronization,
예:
private static Singleton INSTANCE;
public static Singleton getInstance(){
if(INSTANCE==null){
synchronized(Singelton.class){
//Double checking
if(INSTANCE==null){
INSTANCE=new Singleton();
}
}
}
}
문제 설명 은 다음 과 같다.
참조 1:
http://www.ibm.com/developerworks/java/library/j-dcl.html
참고 2:
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
참고 1 에서 out-of-order writes 가 원인 이 라 고 언급 한 것 은 INSTANCE=new Singleton()이다.이 줄 의 코드 는 반드시 다음 과 같은 위조 코드 순서에 따라 진행 되 는 것 이 아니다.
1.메모리 할당
2.호출 구조 기
3.INSTANCE 에 할당
어떤 JIT 에 서 는 다음 과 같이 컴 파일 합 니 다.
1.메모리 할당
2.INSTANCE 에 할당
3.호출 구조 기
이른바 out-of-order writes 다.문 제 는 두 번 째 단계 에서 발생 합 니 다.이때 판단(INSTANCE==null)이 실제 로 돌 아 왔 지만 구조 기 가 아직 호출 되 지 않 았 습 니 다.이때 INSTANCE 를 방문 하면 예상 치 못 한 문제 가 발생 할 수 있 습 니 다.
이상 은 모두 널리 알려 진 지식 을 간단하게 반복 하 는 것 이 고 다음은 나의 보충 이다.
2 의'It will work for 32-bit primitive values'절 을 참고 하여 저 에 게 깨 우 침 을 주 었 습 니 다.32 비트 의 원시 유형 에 대한 Double-checked locking 은 가능 하 다 고 언급 했 습 니 다.(실제 관건 은
할당 작업 이 원자 인지 여부).int 에 대한 할당 값 이 원자 인 이상 우 리 는 조금 개선 하여 int hasInitialized 를 도입 할 수 있 습 니 다.
private static int hasInitialized=0;
private static Singleton INSTANCE;
public static Singleton getInstance(){
if(hasInitialized==0){
synchronized(Singelton.class){
//Double checking
if(hasInitialized==0){
INSTANCE=new Singleton();
hasInitialized=1;
}
}
}
}
차이 점 은:
초기 화 완료 여 부 를 hasInitialized==0 으로 판단 하고 NSTANCE=new Singleton()에서 판단 합 니 다.초기 화 완료 확인 을 위해 값 을 부여 합 니 다.
이것 은 고성능 을 유지 할 수 있 을 뿐만 아니 라(대부분의 경우 잠 금 이 없고 동기 화 블록 에 들 어가 지 않 음)스 레 드 안전 도 보장 할 수 있 지 않 습 니까?
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
자바 문자열 풀우리는 Java에서 문자열이 힙 메모리 영역에 저장된다는 것을 알고 있습니다. 이 힙 메모리 내부에는 String Pool이라는 특정 메모리 영역이 있습니다. 문자열 프리미티브를 생성하면 자바 문자열의 불변성 덕분에...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.