>  기사  >  Java  >  Java에서 동기화와 휘발성의 차이점과 연결

Java에서 동기화와 휘발성의 차이점과 연결

黄舟
黄舟원래의
2017-10-19 09:57:451576검색

이 글은 주로 Java에서 휘발성과 동기화 사이의 차이점과 연결에 대한 관련 정보를 소개합니다. 이 글이 이 부분의 내용을 이해하는 데 도움이 되기를 바랍니다. 도움이 필요한 친구들은 Java에서 휘발성과 동기화를 참고할 수 있습니다. connections

이 글은 아마도 휘발성과 동기화의 효과를 비교한 최고의 글일 것입니다. 휘발성은 변수 수정자이고 동기화는 메서드 또는 블록 수정자입니다. 따라서 우리는 이 두 키워드를 사용하여 현재 스레드의 i1 변수 값을 즉시 얻기 위해 변수


  int i1;            int geti1() {return i1;}
volatile int i2;            int geti2() {return i2;}
   int i3;     synchronized int geti3() {return i3;}

geti1()에 액세스하는 세 가지 간단한 방법을 지정합니다. 스레드는 변수의 로컬 복사본을 얻을 수 있으며, 얻은 변수 값은 다른 스레드에서 얻은 값과 반드시 ​​동일할 필요는 없습니다. 특히, 다른 스레드가 i1 값을 수정하는 경우 현재 스레드가 얻은 i1 값이 수정된 값과 다를 수 있습니다. 실제로 Java에는 주 메모리를 사용하여 변수의 현재 정확한 값을 저장하는 주 메모리 메커니즘이 있습니다. 스레드는 변수의 값을 자신의 독립 메모리에 복사하며, 이러한 스레드의 메모리 복사본은 메인 메모리의 값과 다를 수 있습니다. 따라서 실제로는 주 메모리의 i1 값이 1이고 스레드 1과 스레드 2 모두 i1을 변경했지만 업데이트된 값이 주 메모리나 다른 스레드로 다시 전송되지 않는 경우가 발생할 수 있습니다. 스레드에 있음 스레드 1의 i1 값은 2이지만 스레드 2의 i1 값은 3입니다.

반면, geti2()는 메인 메모리에서 i2의 값을 효과적으로 얻을 수 있습니다. 휘발성 변수는 스레드가 주 메모리에서 자체 저장 공간으로 변수 값을 복사하는 것을 허용하지 않습니다. 따라서 휘발성으로 선언된 변수는 모든 스레드에서 동기적으로 데이터를 가져옵니다. 어떤 스레드에서 변수를 변경하더라도 다른 스레드는 즉시 동일한 결과를 얻습니다. 스레드가 자체 데이터 복사본에 액세스하거나 변경하는 것이 더 효율적이기 때문에 휘발성 유형 변수는 일부 성능을 소비합니다.
그러면 휘발성 변수가 이미 스레드 간에 데이터를 동기화할 수 있다면 동기화는 무엇에 사용되나요? 둘 사이에는 두 가지 차이점이 있습니다. 첫째, 동기화는 리스너가 제어하는 ​​잠금을 획득하고 해제합니다. 두 스레드가 모두 리스너(즉, 동일한 객체 잠금)를 사용하는 경우 리스너는 한 번에 하나의 스레드만 코드 블록을 처리하도록 할 수 있습니다. 동기. 또한 동기화는 메모리를 동기화할 수도 있습니다. 실제로 동기화는 모든 스레드 메모리를 주 메모리와 동기화합니다. 따라서 geti3()의 실행 프로세스는 다음과 같습니다.


1 스레드는 리스너로부터 객체의 잠금을 획득합니다. (여기서는 리스너가 잠겨 있지 않다고 가정합니다. 그렇지 않으면 스레드는 리스너가 잠금 해제될 때까지만 객체 잠금을 얻을 수 있습니다)

2. 스레드 메모리는 모든 변수를 업데이트합니다. 즉, 메인에서 변수를 읽습니다. 자신의 변수를 유효하게 만드는 메모리. (JVM은 "dirty" 플래그가 있는 변수만 업데이트되도록 프로세스를 최적화하기 위해 "dirty" 플래그를 사용합니다. 자세한 내용은 JAVA 사양 17.9를 참조하세요.)

3 코드 블록이 실행됩니다. 예를 들어, 반환 값은 주 메모리에서 재설정된 i3의 현재 값입니다. )

4. 변수에 대한 모든 변경 사항은 주 메모리에 다시 기록됩니다. 하지만 이 예에서는 geti3()에는 변경 사항이 없습니다.

5. 스레드는 객체의 잠금을 리스너에게 해제합니다.

그래서 휘발성은 스레드 메모리와 메인 메모리 사이에서 하나의 변수 값만 동기화할 수 있는 반면, 동기화는 스레드 메모리와 메인 메모리 사이의 모든 변수 값을 동기화하고 리스너를 잠그고 해제하여 이를 달성합니다. 분명히 동기화는 휘발성보다 성능면에서 더 비쌉니다.


둘 사이의 차이점에 대해

1. Volatile은 본질적으로 레지스터(작업 메모리)의 현재 변수 값이 불확실하며 주 메모리에서 읽어야 함을 jvm에 알려줍니다. 변수를 사용하면 현재 스레드만 이 변수에 액세스할 수 있으며 다른 스레드는 차단됩니다.

2.휘발성은 변수 수준에서만 사용할 수 있습니다. 동기화는 변수, 메서드 및 클래스 수준에서 사용할 수 있습니다.

3.
휘발성은 변수의 수정 가시성만 얻을 수 있으며 원자성을 보장할 수 없습니다. 동기화 그러면 변수 수정의 가시성과 원자성이 보장될 수 있습니다

4. Volatile은 스레드 차단을 유발하지 않습니다. 동기화는 스레드 차단을 유발할 수 있습니다.

5. 휘발성으로 표시된 변수는 컴파일러에서 최적화되지 않습니다. 동기화로 표시된 변수는 컴파일러에서 최적화될 수 있습니다.


빨간색 글꼴 부분의 이유는 다음과 같습니다.

스레드 A가 변수를 수정했습니다. 종료되기 전에 다른 스레드 B는 수정된 값을 볼 수 있으며 A가 잠금을 해제할 때까지 기다리지 않고 이 변수를 수정할 수 있습니다. Volatile 변수는 잠겨 있지 않기 때문입니다

위 내용은 Java에서 동기화와 휘발성의 차이점과 연결의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.