code

id = 1-id 원자입니까?

codestyles 2020. 10. 22. 08:03
반응형

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

이 답변을 정답으로 표시했습니다. 내 추론 :

  1. 두 개의 스레드를 시작합니다.
  2. 첫 번째가 들어갑니다 run().
  3. JLS 15.26.1 에 따르면 먼저 1 - id. 결과는 0입니다. 스레드의 스택에 저장됩니다. 우리는 그것을 0static 에 저장하려고 id하지만 ...
  4. 붐, 스케줄러가 실행할 두 번째 스레드를 선택합니다.
  5. 따라서 두 번째 스레드는 run(). 정적 id은 여전히 1있으므로 그는 메서드를 실행합니다 pick(). P Q인쇄됩니다.
  6. 스케줄러는 실행할 첫 번째 스레드를 선택합니다. 0스택에서 가져 와서 static에 저장합니다 id. 따라서 첫 번째 스레드도 실행 pick()하고 P Q.

그러나 책에는 다음과 같은 답이 틀렸다고 기록되어 있습니다.

라인이 있기 때문에 잘못 id = 1 - id의 가치 스왑 id사이 01. 동일한 메서드가 두 번 실행될 가능성은 없습니다.

동의하지 않습니다. 위에서 제시 한 시나리오에 대한 가능성이 있다고 생각합니다. 이러한 스왑은 원자 적이 지 않습니다. 내가 잘못?


내가 잘못?

아니요, 귀하의 예시 타임 라인과 마찬가지로 귀하가 절대적으로 옳습니다.

원 자성이 아닌 것 외에도 id동기화가없고 필드가 휘발성이 아니기 때문에 다른 스레드가 쓰기를 선택하는 것은 보장 되지 않습니다.

다음과 같은 참조 자료가 올바르지 않아 다소 당황 스럽습니다.


제 생각에는 연습 시험의 답이 맞습니다. 이 코드에서는 동일한 정적 변수 ID에 액세스 할 수있는 두 개의 스레드를 실행하고 있습니다. 정적 변수는 스택이 아닌 Java의 힙에 저장됩니다. 실행 가능 항목의 실행 순서는 예측할 수 없습니다.

그러나 각 스레드의 id 값을 변경하려면 다음을 수행하십시오.

  1. id의 메모리 주소에 저장된 값을 CPU 레지스트리에 로컬로 복사합니다.
  2. 작업을 수행합니다 1 - id. 엄밀히 말하면 여기서 두 가지 작업이 수행됩니다 (-id and +1).
  3. 결과를 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 method pick () will be executed, printing P Q. Thread two, will evaluate id at that time id = 0; method release() 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 method pick () will be executed, printing P Q. Thread one, will evaluate id at that time id = 0; method release() 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

반응형