Java에서의 휘발성 vs 스태틱
is is is that that that 라고 하는 것이 ?static
합니다.volatile
모든 스레드에 대한 값의 복사본 1개를 의미합니까?
, 어쨋든static
스레드에 왜 '1'로, '1'로, '1'로 해야 할까요?volatile
Java에서 정적 변수를 선언하는 것은 생성된 클래스의 개체 수에 관계없이 복사본이 하나만 있음을 의미합니다.이 변수는 no가 없어도 액세스할 수 있습니다.Objects
전혀 생성되지 않았습니다.그러나 스레드에는 로컬로 캐시된 값이 있을 수 있습니다.
변수가 변동성이 있고 정적이 아닌 경우 각 변수마다 1개의 변수가 있습니다.Object
따라서 표면적으로는 정상 변수와 차이가 없지만 정적 변수와는 전혀 다른 것으로 보입니다.단,Object
필드, 스레드는 변수 값을 로컬로 캐시할 수 있습니다.
즉, 두 개의 스레드가 동시에 동일한 개체의 변수를 업데이트하고 변수가 휘발성으로 선언되지 않은 경우 스레드 중 하나가 오래된 값을 캐시로 가지고 있을 수 있습니다.
여러 스레드를 통해 정적 값에 액세스하더라도 각 스레드는 로컬 캐시된 복사본을 가질 수 있습니다.이를 피하기 위해 변수를 static volatile로 선언하면 글로벌 값마다 스레드가 강제로 읽힙니다.
그러나 휘발성은 적절한 동기화를 대체할 수 없습니다!
§:
private static volatile int counter = 0;
private void concurrentMethodWrong() {
counter = counter + 5;
//do something
counter = counter - 5;
}
" " "의 실행concurrentMethodWrong
동시에 카운터의 최종값이 0과 다를 수 있습니다!
.
private static final Object counterLock = new Object();
private static volatile int counter = 0;
private void concurrentMethodRight() {
synchronized (counterLock) {
counter = counter + 5;
}
//do something
synchronized (counterLock) {
counter = counter - 5;
}
}
아니면 수업을 이용하세요.
스태틱과 휘발성의 차이:
정적 변수:스레드가 2개일 경우(전제:t1
★★★★★★★★★★★★★★★★★」t2
하고 있습니다.는 static으로 선언된 변수를 의미합니다.t1
★★★★★★★★★★★★★★★★★」t2
캐시에 변수 를할 수 는 ""에 의해 ."t1
에 대한 .t2
시합니니다다
스태틱 변수는 오브젝트 컨텍스트에서 사용됩니다.이 경우 한 오브젝트에 의해 이루어진 갱신은 같은 클래스의 다른 모든 오브젝트에 반영되지만 스레드 컨텍스트에서는 사용되지 않습니다.스태틱 변수에 대한 한 스레드의 갱신은 모든 스레드(로컬캐시)에 대한 변경을 즉시 반영하지 않습니다.
휘발성 변수:스레드가 2개일 경우(전제:t1
★★★★★★★★★★★★★★★★★」t2
하고 있습니다.즉, volatile은 volatile로 선언된 변수를 갱신하고 있습니다.t1
★★★★★★★★★★★★★★★★★」t2
volatile로 선언된 변수를 제외하고 오브젝트의 자체 로컬캐시를 만들 수 있습니다.따라서 volatile 변수는 다른 스레드에 의해 갱신되는 메인복사본을 1개만 가지며 한 스레드에서 volatile 변수에 대해 갱신된 내용은 다른 스레드에 즉시 반영됩니다.
다른 답변과 함께 하나의 이미지를 추가하고 싶습니다(그림은 알기 쉽게 합니다).
static
변수를 개별 스레드에 대해 캐시할 수 있습니다.멀티 스레드 환경에서 한 스레드가 캐시된 데이터를 수정하는 경우 해당 데이터는 복사본이 있기 때문에 다른 스레드에 반영되지 않을 수 있습니다.
volatile
선언을 사용하면 스레드가 데이터를 캐시하지 않고 공유 복사본만 사용할 수 있습니다.
생각에는static
★★★★★★★★★★★★★★★★★」volatile
전혀 관계가 없다Atomic Access와 왜 Atomic Access를 사용하는지, 인터리브가 무엇인지 이해하기 위해 java 튜토리얼을 읽는 것이 좋습니다.
간단히 말하면
스태틱:
static
변수는 객체가 아닌 클래스와 관련지어집니다.클래스의 모든 인스턴스는 메모리 내의 하나의 고정 위치에 있는 클래스 변수를 공유합니다.휘발성:이 키워드는 클래스 변수와 인스턴스 변수 모두에 적용할 수 있습니다.
휘발성 변수를 사용하면 메모리 일관성 오류의 위험을 줄일 수 있습니다. 휘발성 변수에 대한 쓰기는 동일한 변수의 후속 읽기와 occurs-before 관계를 설정하기 때문입니다.즉, 휘발성 변수에 대한 변경은 항상 다른 스레드에 표시됩니다.
이 기사를 참조해 주세요.Javin Paul
이데올로기 때문에
「 」가 volatile
키워드, 각 스레드 스택의 변수 값이 다를 수 있습니다.를 음음음음음음음음 로 한다.volatile
서 말하는 은 '아예'입니다.variable
중 하나일 수 .static
또는 (class) 변수instance
아, 네.
문의에 대해서:
어쨌든 정적 변수 값도 모든 스레드에 대해 하나의 값이 됩니다. 그런데 휘발성을 사용해야 하는 이유는 무엇입니까?
★★★★★★★★가 필요한 경우instance
수 .static
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★!static
변수입니다. 그림과 같이 스레드 캐시로 인해 일관성이 보장되지 않습니다.
「」를 사용합니다.volatile
는 휘발성 쓰기가 오류 .즉, 휘발성 변수에 대한 변경은 항상 다른 스레드에 표시됩니다.
또한 스레드가 휘발성 변수를 읽을 때 휘발성에 대한 최신 변경뿐만 아니라 변경 => 메모리 일관성 오류를 일으킨 코드의 부작용도 휘발성 변수를 통해 여전히 가능하다는 것을 의미합니다.부작용을 방지하려면 동기 변수를 사용해야 합니다.하지만 자바에는 더 나은 솔루션이 있습니다.
동기화된 코드를 통해 이러한 변수에 액세스하는 것보다 단순한 원자 변수 액세스를 사용하는 것이 더 효율적입니다.
의 java.util.concurrent
하지 않는 합니다.
상세한 것에 대하여는, 이 동시성 관리 문서의 개요를 참조해 주세요.
특히 원자 변수를 살펴보세요.
관련 SE 질문:
휘발성 변수 값 액세스는 메인 메모리에서 직접 이루어집니다.다중 스레드 환경에서만 사용해야 합니다. 정적 변수는 한 번 로드됩니다.단일 스레드 환경에서 사용되는 경우 변수의 복사본이 업데이트되고 스레드가 하나뿐이므로 변수에 액세스하는 데 아무런 문제가 없습니다.
멀티스레딩 환경에서 static 변수를 사용하는 경우 원하는 결과를 기대하면 문제가 발생합니다.각 스레드에 자체 복사본이 있기 때문에 한 스레드에서 정적 변수의 증가 또는 감소는 다른 스레드에 반영되지 않을 수 있습니다.
static 변수에서 원하는 결과를 예상한 경우 volatile with static을 멀티캐스팅으로 사용하면 모든 것이 해결됩니다.
정적 변수가 스레드 로컬 메모리에 캐시되었는지 여부를 알 수 없습니다.그러나 동일한 오브젝트(obj)에 접속하는 2개의 스레드(T1, T2)를 실행했을 때 T1 스레드로 static variable을 갱신했을 때 T2에 반영되었습니다.
변수를 static으로 선언하면 변수의 복사본은 1개뿐입니다.따라서 서로 다른 스레드가 변수에 액세스할 때마다 변수에 대한 최종 값은 1개뿐입니다(변수에 할당된 메모리 위치는 1개뿐이기 때문입니다).
변수가 휘발성으로 선언되면 모든 스레드에 변수의 자체 복사본이 있지만 값은 기본 메모리에서 가져옵니다.따라서 모든 스레드의 변수 값은 동일합니다.
따라서 두 경우 모두 변수 값이 모든 스레드에서 동일하다는 것이 주요 포인트입니다.
언급URL : https://stackoverflow.com/questions/2423622/volatile-vs-static-in-java
'programing' 카테고리의 다른 글
'for' 루프에서 1씩 증가할 때 != 대신 > (<)를 사용해야 하는 기술적 이유가 있습니까? (0) | 2022.08.07 |
---|---|
register Natives() 메서드는 무엇을 합니까? (0) | 2022.08.07 |
webpack 또는 browserify를 사용하지 않고 .vue 파일을 .js 파일로 컴파일합니다. (0) | 2022.08.07 |
C에서 스택에 "클래스"를 만들고 있습니까? (0) | 2022.08.07 |
Vuex 스토어에서 알 수 없는 로컬 작업 유형을 가져오는 중 (0) | 2022.08.07 |