id = 1-id 원자입니까?
OCP Java SE 6 프로그래머 연습 시험 291 페이지, 질문 25 :
public class Stone implements Runnable {
static int id = 1;
public void run() {
id = 1 - id;
if (id == 0)
pick();
else
release();
}
private static synchronized void pick() {
System.out.print("P ");
System.out.print("Q ");
}
private synchronized void release() {
System.out.print("R ");
System.out.print("S ");
}
public static void main(String[] args) {
Stone st = new Stone();
new Thread(st).start();
new Thread(st).start();
}
}
대답 중 하나는 다음과 같습니다.
출력은
P Q P Q
이 답변을 정답으로 표시했습니다. 내 추론 :
- 두 개의 스레드를 시작합니다.
- 첫 번째가 들어갑니다
run()
. - JLS 15.26.1 에 따르면 먼저
1 - id
. 결과는0
입니다. 스레드의 스택에 저장됩니다. 우리는 그것을0
static 에 저장하려고id
하지만 ... - 붐, 스케줄러가 실행할 두 번째 스레드를 선택합니다.
- 따라서 두 번째 스레드는
run()
. 정적id
은 여전히1
있으므로 그는 메서드를 실행합니다pick()
.P Q
인쇄됩니다. - 스케줄러는 실행할 첫 번째 스레드를 선택합니다.
0
스택에서 가져 와서 static에 저장합니다id
. 따라서 첫 번째 스레드도 실행pick()
하고P Q
.
그러나 책에는 다음과 같은 답이 틀렸다고 기록되어 있습니다.
라인이 있기 때문에 잘못
id = 1 - id
의 가치 스왑id
사이0
와1
. 동일한 메서드가 두 번 실행될 가능성은 없습니다.
동의하지 않습니다. 위에서 제시 한 시나리오에 대한 가능성이 있다고 생각합니다. 이러한 스왑은 원자 적이 지 않습니다. 내가 잘못?
내가 잘못?
아니요, 귀하의 예시 타임 라인과 마찬가지로 귀하가 절대적으로 옳습니다.
원 자성이 아닌 것 외에도 id
동기화가없고 필드가 휘발성이 아니기 때문에 다른 스레드가 쓰기를 선택하는 것은 보장 되지 않습니다.
다음과 같은 참조 자료가 올바르지 않아 다소 당황 스럽습니다.
제 생각에는 연습 시험의 답이 맞습니다. 이 코드에서는 동일한 정적 변수 ID에 액세스 할 수있는 두 개의 스레드를 실행하고 있습니다. 정적 변수는 스택이 아닌 Java의 힙에 저장됩니다. 실행 가능 항목의 실행 순서는 예측할 수 없습니다.
그러나 각 스레드의 id 값을 변경하려면 다음을 수행하십시오.
- id의 메모리 주소에 저장된 값을 CPU 레지스트리에 로컬로 복사합니다.
- 작업을 수행합니다
1 - id
. 엄밀히 말하면 여기서 두 가지 작업이 수행됩니다(-id and +1)
. - 결과를
id
힙 의 메모리 공간으로 다시 이동합니다 .
This means that although the id value can be changed concurrently by any of the two threads, only the initial and final values are mutable. Intermediate values will not be modified by one another.
Futhermore, analysis of the code can show that at any point in time, id can only be 0 or 1.
Proof:
Starting value id = 1; One thread will change it to 0 (
id = 1 - id
). And the other thread will bring it back to 1.Starting value id = 0; One thread will change it to 1 (
id = 1 - id
). And the other thread will bring it back to 0.
Therefore, the value state of id is discrete either 0 or 1.
End of Proof.
There can be two possibilities for this code:
Possibility 1. Thread one accesses the variable id first. Then the value of id (
id = 1 - id
changes to 0. Thereafter, only the methodpick ()
will be executed, printingP Q
. Thread two, will evaluate id at that timeid = 0
; methodrelease()
will then be executed printing R S. As a result,P Q R S
will be printed.Possibility 2. Thread two accesses the variable id first. Then the value of id (
id = 1 - id
changes to 0. Thereafter, only the methodpick ()
will be executed, printingP Q
. Thread one, will evaluate id at that timeid = 0
; methodrelease()
will then be executed printing R S. As a result,P Q R S
will be printed.
There are no other possibilities. However, it should be noted that variants of P Q R S
such as P R Q S
or R P Q S
, etc. may be printed due to pick()
being a static method and is therefore shared between the two threads. This leads to the simultaneous execution of this method which could result in printing the letters in a different order depending on your platform.
However in any case, never will either the method pick()
or release ()
be executed twice as they are mutually exclusive. Therefore P Q P Q
will not be an output.
참고URL : https://stackoverflow.com/questions/27089196/is-id-1-id-atomic
'code' 카테고리의 다른 글
jQuery 1.4.1에서 JSON stringify 누락? (0) | 2020.10.22 |
---|---|
Java 및 .NET 기술 / 프레임 워크의 유사점 (0) | 2020.10.22 |
JPA : @JoinColumn과 @PrimaryKeyJoinColumn의 차이점은 무엇입니까? (0) | 2020.10.22 |
파이썬에서 클래스를 확장하는 방법은 무엇입니까? (0) | 2020.10.22 |
Android 뷰 수명주기 (상태 다이어그램)를 그래픽으로 표현한 것이 있습니까? (0) | 2020.10.22 |