자바 Volatile 응용 단일 모드 구현 프로 세 스 분석
단선 에서 의 단일 모드 코드 를 돌 이 켜 보 세 요.
굶 주 린 사람 식
public class sington(){
public final static INSTANCE = new singleton();
private singleton(){}
}
두 번 째:jdk 1.5 이후 매 거 진 형식 으로매 거 유형:이 유형의 대상 이 유한 하 다 는 것 을 나타 내 는 몇 가지 유형
우 리 는 한 개 로 한정 할 수 있 는데,단 례 라 고 부른다
public enum Singleto{
INSTANCE
}
세 번 째 정적 코드 블록
public class Singleton{
public final static INSTANCE;
static{
INSTANCE = new Singleton();
}
private Singleton(){}
}
게으름뱅이 구조 기 민영화이 유일한 인 스 턴 스 를 정적 변수 로 저장 합 니 다.
이 인 스 턴 스 를 가 져 오 는 정적 방법 을 제공 합 니 다.
public class Singleton{
private static Singleton INSTANCE;
private Singleton(){}
public static Singleton getInstance(){
if(instance==null){
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
public class SingletonDemo {
private static SingletonDemo instance = null;
private SingletonDemo () {
System.out.println(Thread.currentThread().getName() + "\t SingletonDemo");
}
public static SingletonDemo getInstance() {
if(instance == null) {
instance = new SingletonDemo();
}
return instance;
}
public static void main(String[] args) {
// ==
System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
}
}
마지막 출력 결과:그러나 다 중 스 레 드 환경 에서 우리 의 단일 모델 은 같은 대상 입 니까?
public class SingletonDemo {
private static SingletonDemo instance = null;
private SingletonDemo () {
System.out.println(Thread.currentThread().getName() + "\t SingletonDemo");
}
public static SingletonDemo getInstance() {
if(instance == null) {
instance = new SingletonDemo();
}
return instance;
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
SingletonDemo.getInstance();
}, String.valueOf(i)).start();
}
}
}
아래 의 결 과 를 통 해 알 수 있 듯 이 우 리 는 Singleton Demo.getInstance()를 통 해 얻 은 대상 은 같은 것 이 아니 라 아래 의 몇 개의 스 레 드 에 의 해 만들어 진 것 입 니 다.그러면 다 중 스 레 드 환경 에서 단일 모델 은 어떻게 보장 합 니까?해결 방법
synchronized 키워드 도입
public synchronized static SingletonDemo getInstance() {
if(instance == null) {
instance = new SingletonDemo();
}
return instance;
}
출력 결과:Synchronized 키 워드 를 도입 함으로써 높 은 병발 환경 에서 의 단일 모델 문 제 를 해결 할 수 있 음 을 알 수 있 습 니 다.
그러나 synchronized 는 중량급 동기 화 체제 로 하나의 스 레 드 만 동시에 방문 하여 인 스 턴 스 를 얻 는 방법 을 허용 하지만 데이터 의 일치 성 을 확보 하기 위해 동시성 을 낮 추 었 기 때문에 사용 하 는 것 이 비교적 적다.
해결 방법
DCL Double Check Lock 양단 잠 금 메커니즘 도입 을 통 해
public static SingletonDemo getInstance() {
if(instance == null) {
// ,
synchronized (SingletonDemo.class) {
if(instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
마지막 출력 결 과 는:출력 결 과 를 보면 단일 모델 의 정확성 을 확보 할 수 있 지만 위의 방법 에는 문제 가 존재 한다.
DCL(양단 검 쇄)메커니즘 이 반드시 라인 이 안전 한 것 은 아니다.왜냐하면 지령 재배 열 이 존재 하기 때문이다.volatile 에 가입 하면 지령 재배 열 을 금지 할 수 있다
이 유 는 한 스 레 드 가 첫 번 째 검 측 을 실 행 했 을 때 인 스 턴 스 가 null 이 아 닌 것 을 읽 었 기 때 문 입 니 다.인 스 턴 스 의 참조 대상 이 실례 화 되 지 않 았 을 수도 있 습 니 다.왜냐하면 instance=new SingletonDemo();다음 세 단계 로 나 누 어 완성 할 수 있 습 니 다.
즉,리 셋 후 단계 2 를 실행 하고 인 스 턴 스 를 가 져 오 려 고 할 때 null 을 얻 을 수 있 습 니 다.대상 의 초기 화가 완료 되 지 않 았 고 리 셋 후 단계 3 이 완성 되 었 기 때문에 단일 모드 의 코드 를 실행 할 때 인 스 턴 스 인 스 턴 스 인 스 턴 스 를 다시 만 듭 니 다.
명령 정렬 은 직렬 의미 의 집행 일치 성(단일 스 레 드)만 보장 하지만 다 중 스 레 드 간 의 의미 일치 성 은 관계 되 지 않 습 니 다.
따라서 하나의 스 레 드 가 intance 에 접근 하지 않 을 때 intance 인 스 턴 스 가 초기 화 되 지 않 았 기 때문에 스 레 드 안전 에 문제 가 생 겼 습 니 다.
따라서 volatile 을 도입 하여 명령 재배 치 문제 가 발생 하도록 하고 단일 모델 의 스 레 드 안전성 을 확보 해 야 한다.
private static volatile SingletonDemo instance = null;
최종 코드
public class SingletonDemo {
private static volatile SingletonDemo instance = null;
private SingletonDemo () {
System.out.println(Thread.currentThread().getName() + "\t SingletonDemo");
}
public static SingletonDemo getInstance() {
if(instance == null) {
// a , d
synchronized (SingletonDemo.class) //b
{
//c volitale 。
if(instance == null) {
// d
instance = new SingletonDemo();
}
}
}
return instance;
}
public static void main(String[] args) {
// // ==
// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
// System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());
for (int i = 0; i < 10; i++) {
new Thread(() -> {
SingletonDemo.getInstance();
}, String.valueOf(i)).start();
}
}
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.