자바 synchronized 가시 적 프로 세 스 분석 실현

JMM synchronized 에 관 한 두 가지 규정:
1)스 레 드 잠 금 을 풀기 전에 공유 변수의 최신 값 을 주 메모리 에 새로 고 쳐 야 합 니 다.
2)스 레 드 잠 금 을 추가 할 때 작업 메모리 에서 공유 변수의 값 을 삭제 하고 공유 변 수 를 사용 할 때 메 인 메모리 에서 최신 값 을 다시 가 져 와 야 합 니 다.
(메모:자물쇠 추가 와 잠 금 해 제 는 같은 자물쇠 가 필요 합 니 다)
상기 두 가 지 를 통 해 synchronized 가 가시 성 을 실현 할 수 있 음 을 볼 수 있 습 니 다.또한,synchronized 는 동기 잠 금 이 있 기 때문에 원자 성도 가지 고 있 습 니 다.
다 중 스 레 드 에서 프로그램 이 교차 하여 실 행 될 때 정렬 을 다시 하면 메모리 에 문제 가 생 길 수 있 습 니 다.
다음은 코드 를 보 겠 습 니 다.

/**
 * synchronized       (  )、   
 * 
 * @author xuwenjin
 */
public class SynchronizedDemo {
  //    
  private boolean ready = false;
  private int result = 0;
  private int number = 1;
  /**
   *    
   */
  public void write() {
    ready = true; //1.1
    number = 2;  //1.2
  }
  /**
   *    
   */
  public void read() {
    if (ready) {       //2.1
      result = number * 3; //2.2
    }
    System.out.println("result:" + result);
  }
  //     
  private class WriteReadThread extends Thread {
    
    private boolean flag = false;    
    public WriteReadThread(boolean flag){
      this.flag = flag;
    }    
    @Override
    public void run() {
      if (flag) {
        write();
      }else {
        read();
      }
    }
  }
  public static void main(String[] args) {
    SynchronizedDemo demo = new SynchronizedDemo();
    //         
    demo.new WriteReadThread(true).start();
    //         
    demo.new WriteReadThread(false).start();
  }
}
위의 코드 는 다음 과 같은 실행 순서 가 나타 날 수 있 습 니 다.
1)1.1-->1.2-->2.1-->2.2 result 의 값 은 6(정상 상황)
2)1.1-->2.1-->2.2-->1.2 result 의 값 은 3(스 레 드 가 1.1 을 실행 한 후에 스 레 드 를 읽 기 시작 합 니 다)
3)1.2-->2.1-->2.2-->1.1 result 의 값 은 0(1.1 과 1.2 의 정렬)
  4)...
물론 정렬 과 스 레 드 의 교차 집행 으로 인해 여러 가지 실행 순서 가 나 올 수 있 습 니 다.
공유 변수 가 온라인 에서 보이 지 않 는 원인:
  • a.스 레 드 의 스 레 드 실행
  • b.정렬 결합 스 레 드 교차 집행
  • c.공유 변수 가 업 데 이 트 된 후의 값 은 작업 메모리 와 메 인 메모리 사이 에서 제때에 업데이트 되 지 않 았 습 니 다
  • 그렇다면 가시 적 인 문 제 는 어떻게 해결 할 것 인가?다음 우리 주인공 등장:synchronized
    안전 한 코드:
    
    /**
       *    
       */
      public synchronized void write() {
        ready = true; //1.1
        number = 2;  //1.2
      }
      /**
       *    
       */
      public synchronized void read() {
        if (ready) {       //2.1
          result = number * 3; //2.2
        }
        System.out.println("result:" + result);
      }
    synchronized 의 원자 성,가시 성 으로 인해 상기 에서 말 한 세 가지 문 제 를 완벽 하 게 해결 할 수 있 습 니 다.그러나 읽 기 스 레 드 와 쓰기 스 레 드 의 실행 순 서 는 정 해 지지 않 기 때문에 result 의 결 과 는 여전히 6 또는 0 이 나타 납 니 다.
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기