java 다중 루틴 프로그래밍 사용 Synchronized 블록 동기화 방법

synchronized 키워드는 두 가지 용법이 있습니다.첫 번째는 에서 소개한 방법의 정의에 직접 사용된다.또 하나는 synchronized 블록이다.우리는 synchronized 블록을 통해 대상 변수를 동기화할 수 있을 뿐만 아니라synchronized 블록을 사용하여 클래스의 정적 방법과 비정적 방법을 동기화할 수 있습니다.synchronized 블록의 구문은 다음과 같습니다.

public void method()
{
    … …
    synchronized( )
    {
        … …
    }
}
1. 비정태 클래스 방법의 동기화
'Synchronized 키워드 동기화 방법을 사용합니다'라는 글에서 우리는synchronized 키워드를 사용하여 방법을 정의하면 클래스에서synchronzied 키워드로 정의된 정적 방법이나 비정적 방법을 잠그는 것을 알고 있지만, 이것은 이해하기 어렵다.만약synchronized 블록을 사용하여 같은 효과를 얻으면 왜 이런 효과가 발생했는지 이해하기 어렵지 않다.synchronized 블록을 사용하여 클래스의 모든 동기화 비정상적인 방법을 잠그려면,this를 synchronized 블록의 매개 변수로 synchronized 블록국에 전송해야 합니다. 코드는 다음과 같습니다. synchronized 블록을 통해 비정상적인 방법을 동기화합니다.

public class SyncBlock
   {
       public void method1()
       {
           synchronized(this)  // method1 synchronized
           {
               … …
           }
       }
       public void method2()
       {
           synchronized(this)  // method2 synchronized
           {
               … …
           }
       }
       public synchronized void method3() 
       {
           … …
       }
   }
위의 코드의method1과method2 방법에서synchronized 블록을 사용했습니다.017행의method3 방법은 여전히synchronized 키워드를 사용하여 방법을 정의합니다.같은 SyncBlock 클래스 인스턴스를 사용할 때 이 세 가지 방법은 실행 중인 방법 하나만 있으면 다른 두 가지 방법은 동기화 자물쇠를 얻지 못해 막힙니다.synchronized 블록을 사용할 때synchronized 키워드와 같은 효과를 얻으려면 모든 코드를synchronized 블록에 써야 합니다. 그렇지 않으면 현재 방법의 모든 코드와 다른 방법을 동기화할 수 없습니다.this를 synchronized 블록으로 사용하는 매개 변수 외에 SyncBlock도 사용할 수 있습니다.this는synchronized 블록의 매개 변수로 같은 효과를 냅니다.내부 클래스(InnerClass)의 방법에서synchronized 블록을 사용할 때this는 내부 클래스만 표시하고 외부 클래스(OuterClass)와 관계가 없습니다.그러나 내류의 비정태 방법은 외류의 비정태 방법과 동기화할 수 있다.예를 들어 내부 클래스 InnerClass에 method4 방법을 추가하고 method4 방법과 SyncBlock의 세 가지 방법을 동기화합니다. 코드는 다음과 같습니다. 내부 클래스의 비정적 방법과 외부 클래스의 비정적 방법을 동기화합니다

public class SyncBlock
{
    … …
    class InnerClass
    {
        public void method4()
        {
            synchronized(SyncBlock.this)
            {
                … …
            }
        }
    }
    … …
}
위의 SyncBlock 클래스의 새로운 버전에서 InnerClass 클래스의method4 방법과 SyncBlock 클래스의 다른 세 가지 방법이 동기화되었기 때문에method1,method2,method3,method4 네 가지 방법은 같은 시간에 한 방법만 실행할 수 있습니다.Synchronized 블록이 정상적으로 실행되었든 프로그램 오류로 인해 비정상적으로 synchronized 블록을 종료했든 현재synchronized 블록이 가지고 있는 동기화 자물쇠는 자동으로 방출됩니다.따라서synchronized 블록을 사용할 때 동기화 자물쇠의 방출 문제를 걱정할 필요가 없습니다.
둘째, 정적 클래스 방법의 동기화는 정적 방법을 호출할 때 대상의 실례가 반드시 만들어지지 않기 때문이다.따라서this를 사용하여 정적 방법을 동기화할 수 없으며, 클래스 대상을 사용하여 정적 방법을 동기화해야 한다.코드는 다음과 같습니다. synchronized 블록을 통해 정적 방법을 동기화합니다

public class StaticSyncBlock
{
       public static void method1()
       {
           synchronized(StaticSyncBlock.class) 
           {
               … …
           }
       }
       public static synchronized void method2() 
       {
           … …
       }
   }
정적 방법을 동기화할 때 클래스의 정적 필드class를 사용하여 클래스 대상을 얻을 수 있습니다.전례에서method1과method2 방법은 동시에 하나의 방법만 실행할 수 있습니다.class 필드를 사용하여 클래스 대상을 얻는 것 외에 실례적인 getClass 방법으로 클래스 대상을 얻을 수 있습니다.위의 코드는 다음과 같이 수정할 수 있습니다. getClass 방법으로 Class 대상을 얻을 수 있습니다.

public class StaticSyncBlock
{
    public static StaticSyncBlock instance;
    public StaticSyncBlock()
    {
        instance = this;
    }
    public static void method1()
    {
       synchronized(instance.getClass())
       {

       }
    }  
}
위 코드에서public의 정적 instance를 통해 StaticSyncBlock 클래스의 실례를 얻고 이 실례의 getClass 방법을 통해 클래스 대상을 얻습니다(한 클래스의 모든 실례는 getClass 방법을 통해 얻은 것은 같은 클래스 대상이기 때문에 어떤 실례의 getClass 방법을 사용해도 됩니다).우리는 또한 Class 대상을 통해 서로 다른 종류의 정적 방법을 동기화할 수 있다. 예를 들어 Test 클래스의 정적 방법인method와StaticSyncBlock 클래스의 두 가지 정적 방법을 동기화할 수 있다. 코드는 다음과 같다. Test 클래스의method 방법과StaticSyncBlock 클래스의method1,method2 방법을 동기화할 수 있다

public class Test
   {
       public static void method()
       {
           synchronized(StaticSyncBlock.class)
           {

           }
       }
   }
주의:synchronized 블록 동기화 방법을 사용할 때, 비정적 방법은this를 사용하여 동기화할 수 있으며, 정적 방법은 반드시 Class 대상을 사용하여 동기화해야 합니다.그들은 서로 영향을 주지 않는다.물론 비정적 방법에서 클래스 대상을 사용하여 정적 방법을 동기화할 수도 있다.그러나 정적 방법에서this를 사용하여 비정적 방법을 동기화할 수 없습니다.이 점은synchronized 블록 동기화 방법을 사용할 때 주의해야 한다.

좋은 웹페이지 즐겨찾기