"프로그램이 스레드 내 의미론을 만족하는지"를 간단히 설명 할 수 있습니까? 그러한 의미를 만족시키고 만족시키지 않는 프로그램의 간단한 예제를 제공하는 것이 가능한가?스레드 내 의미 이해하기
답변
내부 스레드 의미론의 개념은 Java 메모리 모델을 다루는 JLS section 17.4에서 논의됩니다. JMM은 JVM에 의한 Java 프로그램 실행에 대한 요구 사항 및 제한 사항 세트입니다. 다음은 17.4의 텍스트 관련 섹션입니다.
메모리 모델은 프로그램의 모든 지점에서 읽을 수있는 값을 결정합니다. 고립 된 각 스레드의 동작은 각 읽기에서 보이는 값이 메모리 모델에 의해 결정된다는 점을 제외하고는 해당 스레드의 의미에 따라 관리되어야합니다. 이것을 참조 할 때, 프로그램은 스레드 내 의미론을 따릅니다. 내부 스레드 의미론은 단일 스레드 프로그램에 대한 의미이며 스레드 내의 읽기 작업에서 볼 수있는 값을 기반으로 스레드의 동작을 완전히 예측할 수 있도록합니다. 실행에서 쓰레드 t의 동작이 합법적인지를 결정하기 위해,이 규격의 나머지 부분에서 정의 된 것처럼 단일 쓰레드 컨텍스트에서 수행되는 것처럼 쓰레드 t의 구현을 평가한다.
이것은 단일 스레드에 관한 한 객체의 필드에서 볼 수있는 값이 필드의 초기 값 (0, false 또는 null)이거나이 스레드가 이전에 작성한 값 .
이것은 매우 초보적 인 것처럼 분명합니다. 왜 그걸 진술 해?
몇 int
필드 단일 스레드 자바 프로그램을 고려
field1 = 1; // 1
field2 = 2; // 2
field3 = field1 + field2; // 3
을 다음 명확하게 field3
의 값이 3입니다해야하기 때문에 라인 3 해야에서 field1
및 field2
에 표시 값 첫 번째 및 두 번째 줄에 기록 된 이전 값을 반영합니다. field1
또는 field2
에 대한 0의 초기 값이 줄 3의 계산에 사용 된 경우 올바르지 않습니다. 이러한 필드의 할당은 프로그램에서 계산보다 이전에 발생하기 때문입니다.
덜 좁은 것은 이 아닌 인 제약입니다. 예를 들어 field1
및 field2
의 주문에 대한 제한이 없습니다. JVM은 1 행보다 먼저 2 행을 실행할 수 있으며 프로그램의 결과는 동일합니다. 또는 쓰기를 field1
및 field2
으로 지연하고 이러한 값을 레지스터에 유지하고 3 행에서 레지스터 기반 추가를 수행 할 수 있습니다. 모든 필드의 실제 쓰기는 훨씬 늦어 질 때까지 지연 될 수 있습니다. 또는 나중에 값이이 스레드에 의해 겹쳐 쓰여지더라도 완전히 생략 할 수도 있습니다. 다시 말하지만, 프로그램의 결과는 같습니다.
그 점 : JVM은 프로그램 실행을 자유롭게 재정렬하여 (주로 더 빠르게 실행할 수 있음) 단일 스레드로 실행되는 경우 해당 프로그램의 결과를 변경하지 않는 한 . 이러한 제약 조건은 내부 스레드 의미론이라고합니다. 스레드 내 의미를 위반하지 않는 재배치는 허용됩니다.
(는 "내 스레드 의미를 따르는 프로그램"에 대해 이야기 위에 인용 한 단락하지만 정말 의미하는 것은 프로그램의 실행 유의는 17.4로 내 스레드 의미. 나중에 섹션에서 텍스트, 순종 0.7은 프로그램의 실행이 내 스레드 일관성을 순종 여부 또는 내 스레드 의미와 일치에 행동의 세트 수행 여부 참조, 더 정확하다.)
완벽한, 감사합니다! –
흥미로운 사실은 "... 각 읽기에서 보이는 값이 예제의 맥락에서 메모리 모델에 의해 결정된다는 것을 제외하고는 ..."을 의미합니까? – Vitaly
@Vitaly 모든 것을 의미하는 것은 아닙니다. 예제 프로그램의 의미를 살펴보면 * variables * "field1"과 "field2"를 할당 한 다음 해당 변수의 값을 계산에서 사용하여 "field3"변수에 할당합니다. 이것에 메모리 모델을 추가하는 것은 "field1"및 "field2"에 대한 할당이 * 쓰기 * 연산을 생성한다는 것을 의미하며 표현에서의 사용은 "field3"에 대한 * 쓰기 * 연산이 뒤따라 나오는 * read * 연산을 의미합니다. 변수 할당에서 메모리 읽기 및 쓰기 작업으로 어휘를 옮겼습니다. 그것이 메모리 모델의 영향입니다. –
내가 생각할 겁니다 "내, 스레드 "는 단일 스레드를 의미합니다. 그러나 문맥이 없으면 말하기가 어려울 것입니다. 단일 스레드로 안전하지 않은 코드를 작성하는 것은 거의 불가능합니다. 참고 : lazySet()은 예외입니다. –
@ PeterLawrey 실제로 iirc 자바 메모리 모델 JSR (133) 종류는 "내부 스레드"가 무엇을 의미하는지 정의합니다 –
@MateuszDymczyk 나는 그들이 같은 것을 이야기하고 있다고 생각합니다. 이것이 사실이 아니라면 정말 놀랍기 때문에 거의 문제가되지 않습니다. –