둘 이상의 스레드가 필드에 액세스할 수 있는 경우 해당 필드를 휘발성으로 표시해야 합니까?

StackOverflow https://stackoverflow.com/questions/1621495

  •  06-07-2019
  •  | 
  •  

문제

몇 개의 스레드 읽기(일반적인 동시성 문제, 휘발성 키워드, 메모리 모델) Java의 동시성 문제에 대해 혼란스러워요.

둘 이상의 스레드에서 액세스하는 필드가 많이 있습니다.이를 검토하고 모두 휘발성으로 표시해야 합니까?

클래스를 만들 때 여러 스레드가 클래스에 액세스할지 여부를 알 수 없으므로 모든 필드를 허용하는 것은 안전하지 않습니다. ~ 아니다 휘발성이므로 사용하지 않을 경우가 거의 없다는 것을 이해합니다.이 올바른지?

나에게 이것은 버전 1.5 JVM 이상에만 해당되지만 내 특정 설정에 대한 답변에만 국한되지는 않습니다.

도움이 되었습니까?

해결책

필드가 여러 스레드로 액세스하는 경우 volatile 또는 final, 또는 동기화 된 블록으로 만 액세스합니다. 그렇지 않으면 지정된 값이 다른 스레드에 표시되지 않을 수 있습니다.

클래스는 여러 스레드에 의한 동시 액세스를 위해 특별히 설계되어야합니다. 단순히 필드를 휘발성 또는 최종으로 표시하면 스레드 안전성에 충분하지 않습니다. 일관성 문제 (여러 필드 변경 원자력), 스레드 간 신호에 대한 우려 (예 : 사용 wait 그리고 notify), 등.

따라서 객체가 달리 문서화되지 않는 한 단일 스레드 만 볼 수 있어야한다고 가정하는 것이 가장 안전합니다. 모든 객체를 스레드-안전을 위해 만들기는 필요하지 않으며 소프트웨어 속도로, 더 중요한 것은 개발 비용 측면에서 비용이 많이 듭니다.

대신, 소프트웨어는 동시 스레드가 가능한 한 적게 상호 작용할 수 있도록 설계되어야합니다. 상호 작용하는 지점은 적절한 동시성 제어를 설계 할 수 있도록 명확하게 식별해야합니다.

다른 팁

글쎄, 당신은 다른 질문을 읽었고 이미 답변을 읽었을 것으로 가정하므로 몇 가지 핵심 사항만 강조하겠습니다.

  1. 그 사람들이 변할까?그렇지 않다면 휘발성이 필요하지 않습니다
  2. 그렇다면 한 필드의 값이 다른 필드와 관련되어 있습니까?그렇다면 4번 항목으로 이동하세요.
  3. 얼마나 많은 스레드가 그것을 바꿀 것인가?1개만 있으면 휘발성만 있으면 됩니다.
  4. 2번에 대한 대답이 "아니요"이거나 두 개 이상의 스레드가 이에 쓰려고 한다면 휘발성은 단독으로 사용됩니다. 부족한, 액세스를 동기화해야 할 수도 있습니다.

추가됨:
필드가 객체를 참조하는 경우 자체 필드를 갖게 되며 모든 고려 사항이 이러한 필드에도 적용됩니다.

요청 해야하는 경우 자물쇠를 사용하십시오. volatile 경우에 따라 유용 할 수 있지만 제대로하기가 매우 어렵습니다. 예를 들어:

class Foo {
  private volatile int counter = 0;
  int Increment() {
    counter++;
    return counter;
  }
}

두 스레드가 실행되는 경우 Increment() 동시에 결과가 가능합니다. counter = 1. 컴퓨터가 먼저 검색되기 때문입니다 counter, 하나를 추가 한 다음 다시 저장하십시오. 휘발성은 다른 진술에 비해 특정 순서로 저장 및 부하가 발생하도록 강요합니다.

주목하십시오 synchronized 일반적으로 필요성이 없습니다 volatile - 주어진 필드에 대한 모든 액세스가 동일한 모니터로 보호되는 경우 volatile 필요하지 않을 것입니다.

사용 volatile 잠금 알고리즘을 만드는 것은 매우 어렵습니다. 고집하십시오 synchronized 이미 너무 느린 증거가없고 구현하려는 알고리즘에 대한 자세한 분석을 수행하지 않는 한.

짧은 대답은 아니오입니다. 스레딩 문제는 이것보다 더 많은 생각과 계획이 필요합니다. 보다 이것 휘발성이 스레딩에 도움이 될 때와 그렇지 않은 경우에도 일부 제한 사항. 값의 수정은 올바르게 동기화되어야하지만, 매우 일반적으로 수정하려면 한 번에 하나 이상의 변수의 상태가 필요합니다. 예를 들어 변수가 있고 기준을 충족하면 변경하려고합니다. 배열에서 읽은 내용과 배열에 대한 쓰기는 다른 지침이며 함께 동기화되어야합니다. 휘발성으로는 충분하지 않습니다.

변수가 변이 가능한 객체 (배열 또는 컬렉션)를 참조하는 경우를 고려한 다음 해당 객체와 상호 작용하는 것은 참조가 휘발성이기 때문에 스레드 안전하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top