Synchronized 구현 원리

4310 단어 Java 기반
1. 적용 방법:
2.synchronized 코드 블록 베이스 원리
3. synchronized 방법의 밑바닥 원리

1. 적용 방법:


주로 다음과 같은 3가지 애플리케이션이 있습니다.
  • 실례를 수식하는 방법은 현재 실례에 자물쇠를 추가하는 데 작용하고 동기화 코드에 들어가기 전에 현재 실례의 자물쇠를 획득해야 한다
  • 정적 수식 방법은 현재 클래스 대상의 잠금에 작용하고 동기화 코드에 들어가기 전에 현재 클래스 대상의 잠금
  • 을 획득해야 한다.
  • 수식 코드 블록, 잠금 대상을 지정하고 주어진 대상에 잠금을 가하며 동기화 코드 라이브러리에 들어가기 전에 주어진 대상의 잠금을 획득해야 한다
  • 2.synchronized 코드 블록 베이스 원리


    synchronized로 장식된 동기화 코드 블록을 정의하고 코드 블록에서 공유 변수 i를 조작합니다. 다음과 같습니다.
    public class SyncCodeBlock {
    
       public int i;
    
       public void syncTask(){
           // 
           synchronized (this){
               i++;
           }
       }
    }
    

    상기 코드를 컴파일하고 javap를 사용하여 역컴파일한 후 바이트 코드는 다음과 같다(여기서 우리는 일부 불필요한 정보를 생략한다).
    //=========== syncTask ================
      public void syncTask();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=3, locals=3, args_size=1
             0: aload_0
             1: dup
             2: astore_1
             3: monitorenter  // , 
             4: aload_0
             5: dup
             6: getfield      #2             // Field i:I
             9: iconst_1
            10: iadd
            11: putfield      #2            // Field i:I
            14: aload_1
            15: monitorexit   // , 
            16: goto          24
            19: astore_2
            20: aload_1
            21: monitorexit // , 
            22: aload_2
            23: athrow
            24: return
          Exception table:
          // .......
    }
    SourceFile: "SyncCodeBlock.java"
    

    주로 바이트 코드 중의 다음과 같은 코드를 주목한다
    3: monitorenter  // 
    //..........   
    15: monitorexit   // 
    16: goto          24
    // .......
    21: monitorexit // 
    

    바이트 코드에서 동기화 문장 블록의 실현은 모니터와 모니터 exit 명령을 사용하는 것을 알 수 있다.
    모니터 관리자 명령
    대상마다 모니터 자물쇠가 있습니다.모니터가 점용될 때 잠금 상태가 됩니다. 라인이 모니터 관리자 명령을 실행할 때 모니터의 소유권을 얻으려고 시도합니다. 과정은 다음과 같습니다.
  • 모니터의 진입수가 0이면 이 라인은 모니터에 진입한 다음에 진입수를 1로 설정하면 이 라인은 모니터의 소유자가 된다.
  • 만약에 라인이 이미 이 모니터를 점유하고 다시 들어갈 뿐이라면 모니터에 들어가는 입장수는 1을 더한다.
  • 다른 라인이 모니터를 점용했다면 이 라인은 모니터의 진입 수가 0이 될 때까지 막힌 상태로 들어가서 모니터의 소유권을 다시 시도합니다.

  • 모니터exit 명령
    모니터 xit를 실행하는 라인은 Objectref (즉 대상 자물쇠) 에 대응하는 모니터의 소유자가어야 합니다.
    명령이 실행될 때 모니터의 진입수가 1로 줄어듭니다. 1을 줄인 후 진입수가 0이면, 이 라인은 모니터에서 종료됩니다. 더 이상 이 모니터의 소유자가 아닙니다.이 모니터에 의해 막힌 다른 라인은 이 모니터의 소유권을 얻으려고 시도할 수 있습니다.
     

    3. synchronized 방법의 밑바닥 원리


    방법급의 동기화는 은식이다. 즉, 바이트 코드 명령을 통해 제어할 필요가 없으며, 방법 호출과 되돌아오는 작업을 실현한다.
    JVM은 메소드 상수 풀의 메소드 테이블 구조(method info Structure)에서 ACCSYNCHRONIZED 액세스 플래그는 방법 동기화 여부를 구분합니다.
    메서드가 호출되면 호출 명령은 메서드의 ACC 를 확인합니다.SYNCHRONIZED 액세스 로고가 설정되었는지 여부입니다. 설정되면 실행 루틴은 모니터(가상 기기 규범에서 사용하는 것은 파이프라인이라는 단어)를 가지고 있다가 방법을 실행하고 마지막으로 방법이 완성될 때(정상적으로 완성되었든 비정상적으로 완성되었든) 모니터를 방출합니다.방법이 실행되는 동안 실행 루틴은 모니터를 가지고 있으며 다른 어떤 루틴도 같은 모니터를 얻을 수 없습니다.만약 동기화 방법이 실행되는 동안 이상이 발생하고 방법 내부에서 이 이상을 처리할 수 없다면, 이 동기화 방법이 가지고 있는 모니터는 이상이 동기화 방법 밖으로 던져질 때 자동으로 방출됩니다.다음은 바이트 코드 차원에서 어떻게 실현되는지 살펴보자.
    public class SyncMethod {
    
       public int i;
    
       public synchronized void syncTask(){
               i++;
       }
    }

    javap를 사용하여 역컴파일한 바이트 코드는 다음과 같습니다.
    Classfile /***/src/main/java/com/zejian/concurrencys/SyncMethod.class
      Last modified 2017-6-2; size 308 bytes
      MD5 checksum f34075a8c059ea65e4cc2fa610e0cd94
      Compiled from "SyncMethod.java"
    public class com.hc.concurrencys.SyncMethod
      minor version: 0
      major version: 52
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool;
    
       // 
      //==================syncTask ======================
      public synchronized void syncTask();
        descriptor: ()V
        // ACC_PUBLIC public ,ACC_SYNCHRONIZED 
        flags: ACC_PUBLIC, ACC_SYNCHRONIZED
        Code:
          stack=3, locals=1, args_size=1
             0: aload_0
             1: dup
             2: getfield      #2                  // Field i:I
             5: iconst_1
             6: iadd
             7: putfield      #2                  // Field i:I
            10: return
          LineNumberTable:
            line 12: 0
            line 13: 10
    }
    SourceFile: "SyncMethod.java"
    

     
    참고: Synchronized 및 그 실현 원리,synchronized 실현 원리,http://cmsblogs.com/?p=2071

    좋은 웹페이지 즐겨찾기