>Java >java지도 시간 >Java 이중 확인 잠금 모드란 무엇입니까?

Java 이중 확인 잠금 모드란 무엇입니까?

WBOY
WBOY앞으로
2023-05-19 15:29:491509검색

원인

프로젝트에서 PMD 정적 코드 감지를 수행할 때 이러한 문제가 발생했습니다.

Java에서 사용할 때 부분적으로 생성된 객체가 Double Checked Locking 패턴에 의해 반환될 수 있습니다. 최적화 JRE는 baz 변수에 대한 참조를 할당할 수 있습니다. 참조가 가리키는 개체의 생성자를 호출하기 전에.

참고: Java 5에서는 변수를 휘발성으로 선언하면 이중 확인 잠금이 작동하도록 할 수 있습니다.

아마도 이중 확인 잠금 모드를 사용할 때 불완전하게 초기화된 객체를 반환합니다. 일부 사람들은 부분적으로 초기화된 객체의 개념을 의심할 수 있습니다. 계속 분석해 보세요.

이중 확인 잠금 모드가 무엇인가요?

<code>public static Singleton getSingleton() {<br>    if (instance == null) {                        <br>        synchronized (Singleton.class) {<br>            if (instance == null) {                 <br>                instance = new Singleton();<br>            }<br>        }<br>    }<br>    return instance ;<br>}</code> 

instance == null이 동기화된 코드 블록 내부와 외부 모두에서 판단되는 것을 볼 수 있습니다. 스레드는 동시에 동기화된 코드 블록 외부에서 if 판단을 입력할 수 있습니다. 동기화된 코드 블록 내부에서 null 판단이 수행되지 않으면 여러 인스턴스가 초기화될 수 있습니다.

문제

이런 글쓰기 방식은 완벽해 보이지만 문제가 있거나 완벽하다는 보장은 없습니다. 주된 이유는 instance = new Singleton();이 원자적 연산이 아니기 때문입니다.
객체 생성은 세 부분으로 나눌 수 있습니다:

<code>1.分配对象的内存空间<br>2.初始化对象<br>3.设置instance指向刚分配的内存地址<br>当instance指向分配地址时,instance是不为null的</code> 

그러나 2단계와 3단계 사이에서 순서가 바뀌어 객체 생성 순서가 1-3-2가 될 수 있습니다.
스레드 A는 다음과 같습니다. 처음에는 Singleton 객체를 생성하며, 객체 생성 순서는
인스턴스에 메모리를 할당한 후 스레드 B가 와서 getSingleton() 메서드를 호출합니다. 이때 해당 인스턴스라고 판단합니다. == null이며 인스턴스가 Not null이 아닌 것으로 확인되었습니다.
그러나 현재 인스턴스는 개체를 초기화하지 않았으며 스레드 B는 초기화되지 않은 개체를 반환합니다. Thread B가 인스턴스를 사용할 때 문제가 발생할 수 있습니다. 이것이 Double-Check Lock의 문제입니다.

휘발성을 사용하세요

위의 문제에 대해서는 인스턴스를 휘발성으로 선언하면 위의 문제를 해결할 수 있습니다.

<code>public class Singleton{<br>    private volatile static Singleton instance;<br>    public static Singleton getSingleton() {<br>        if (instance == null) {                        <br>            synchronized (Singleton.class) {<br>                if (instance == null) {                 <br>                    instance = new Singleton();<br>                }<br>            }<br>        }<br>        return instance ;<br>    }<br>}</code> 
단, JDK5 버전 이상에서는 사용해야 합니다.

정적 내부 클래스

<code>public class Singleton {  <br>    private static class SingletonHolder {  <br>        private static final Singleton INSTANCE = new Singleton();  <br>    }  <br>    private Singleton (){}  <br>    public static final Singleton getInstance() {  <br>        return SingletonHolder.INSTANCE; <br>    }  <br>}</code>

현재 권장되는 작성 방법은 스레드 안전 문제 없이 지연 로딩을 달성할 수 있는 정적 내부 클래스를 사용하는 것입니다. 그리고 동기화의 오버헤드를 줄입니다.

위 내용은 Java 이중 확인 잠금 모드란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제