volatile 키워드를 사용해도이 예에서는 코드가 스레드로부터 안전하지 않습니다. 휘발성 키워드는 일반적으로 변수 값 (예 : 클래스 필드)을 읽거나 쓸 때 해당 변수의 최신 값이 주 메모리에서 읽히거나 캐시에서 읽지 않고 주 메모리에 직접 쓰게하는 데 사용됩니다 (예 : CPU 레지스터)를 포함한다. volatile 키워드는 "이 공유 필드에서 캐싱 최적화를 사용하지 마십시오"라고 말하는 방법이며 스레드가 필드의 로컬 복사본을 사용하여 서로의 업데이트를 볼 수없는 문제를 제거합니다.
myclass의 값이 실제로 업데이트되지 않습니다 (즉, myclass를 다시 할당하지 않음). 휘발성이 유용하지 않으며 실제로 스레드를 만들고 싶은 myclass 변수의 업데이트가 아닙니다 이 경우 어쨌든 안전합니다.
실제 클래스를 스레드로부터 안전하게 업데이트하려면 "추가"및 "지우기"주위에 "잠금"을 사용하는 것이 간단합니다. 이렇게하면 한 번에 하나의 스레드 만 myclass의 내부 상태를 업데이트하는 이러한 작업을 수행 할 수 있으므로 병렬로 수행하면 안됩니다.
private readonly object syncObj = new object();
private readonly myclass = new myclass();
......
lock (syncObj)
{
myclass.Add(...)
}
lock (syncObj)
{
myclass.Clear(..)
}
당신도 그런 경우가 없지만, "추가"로 업데이트되는 상태를 읽는 코드를 주위에 잠금 추가해야 다음과 같이
잠금을 사용할 수 있습니다 예제 코드에 나타납니다.
컬렉션에 추가 할 때 왜 잠금이 필요한지 멀티 스레드 코드를 처음 작성할 때 명확하지 않을 수 있습니다. List 또는 ArrayList를 예로 들면, 내부적으로 이러한 콜렉션이 배열을 보조 저장소로 사용하므로 동적으로 "Array"를 확장합니다 (즉, 더 큰 새로운 Array를 만들고 이전 내용을 복사하여). Add가 호출되면 용량이 충족됩니다. 이것은 모두 내부적으로 발생하며이 Array 및 변수의 현재 크기 (실제 배열의 길이가 더 클 수도 있음)와 같은 변수를 유지 관리해야합니다. 따라서 내부 배열을 확장해야하는 경우 컬렉션에 추가하는 과정에 여러 단계가 필요할 수 있습니다. 안전하지 않은 방식으로 여러 스레드를 사용하는 경우 여러 스레드가 추가로 인해 간접적으로 성장을 일으켜 다른 모든 업데이트를 트램프 할 수 있습니다.다중 스레드 문제뿐만 아니라 동시에 다른 스레드가 컬렉션을 읽는 중일 수 있으며 내부 상태가 변경되는 중이라는 문제가 있습니다. 잠금을 사용하면 이러한 작업을 다른 스레드로부터의 간섭없이 수행 할 수 있습니다.
휘발성 필드에만 적용 가능 – Kimi
왜 휘발성으로 만들고 싶습니까? 애플리케이션에 가치를 추가 할 예정입니까? – Shekhar
이제 자신에게 질문하고 동의하십시오. 귀하의 질문 중 거의 90 %가 답변을드립니다. – Incognito