동기화된 키워드에는 두 가지 용도가 있습니다. 첫 번째는 "Synchronized 키워드를 사용하여 클래스 메서드 동기화" 문서에 소개된 대로 메서드 정의에서 직접 사용하는 것입니다. 또 다른 유형은 동기화 블록입니다. 동기화된 블록을 통해서는 객체 변수를 동기화할 수 있을 뿐만 아니라 또한 동기화된 블록을 사용하여 클래스의 정적 메서드와 비정적 메서드를 동기화할 수도 있습니다.
동기화된 블록의 구문은 다음과 같습니다.
다음과 같이 코드 코드를 복사합니다.
공개 무효 방법()
{
… …
동기화됨(표현식)
{
… …
}
}
1. 비정적 클래스 메소드의 동기화
"Synchronized 키워드를 사용하여 클래스 메서드 동기화"라는 기사에서 동기화 키워드를 사용하여 메서드를 정의하면 클래스에서 synchronzied 키워드를 사용하여 정의된 모든 정적 또는 비정적 메서드가 잠긴다는 것을 알고 있지만 이해하기 쉽지 않습니다. 동일한 효과를 얻기 위해 동기화된 블록을 사용한다면 이러한 효과가 발생하는 이유를 이해하는 것은 어렵지 않습니다. 동기화된 블록을 사용하여 클래스의 모든 동기화된 비정적 메소드를 잠그려면 이를 동기화된 블록의 매개변수로 사용하고 이를 동기화된 블록 국가에 전달해야 합니다. 코드는 다음과 같습니다.
동기화된 블록을 통해 비정적 메서드 동기화
다음과 같이 코드 코드를 복사합니다.
공개 클래스 SyncBlock
{
공개 무효 메소드1()
{
동기화(this) // method1 메소드에서 동기화 키워드를 사용하는 것과 동일합니다.
{
… …
}
}
공개 무효 메소드2()
{
동기화(this) // method2 메소드에 대한 동기화 키워드를 사용하는 것과 동일합니다.
{
… …
}
}
공개 동기화 무효 메소드3()
{
… …
}
}
위의 코드에서 동기화된 블록은 method1 및 method2 메서드에 사용됩니다. 017행의 method3 메소드는 여전히 동기화된 키워드를 사용하여 메소드를 정의합니다. 동일한 SyncBlock 클래스 인스턴스를 사용하는 경우 세 가지 메서드 중 하나가 실행되는 동안에는 동기화 잠금을 획득하지 못하기 때문에 나머지 두 메서드는 차단됩니다. 동기화 블록을 사용할 때 동기화 키워드와 동일한 효과를 얻으려면 모든 코드를 동기화 블록에 작성해야 합니다. 그렇지 않으면 현재 메서드의 모든 코드가 다른 메서드와 동기화되지 않습니다.
이것을 동기화된 블록의 매개변수로 사용하는 것 외에도 SyncBlock.this를 동기화된 블록의 매개변수로 사용하여 동일한 효과를 얻을 수도 있습니다.
내부 클래스(InnerClass)의 메소드에서 동기화된 블록을 사용하는 경우 이는 내부 클래스만을 나타내며 외부 클래스(OuterClass)와는 아무런 관련이 없습니다. 그러나 내부 클래스의 비정적 메서드는 외부 클래스의 비정적 메서드와 동기화될 수 있습니다. 예를 들어 내부 클래스 InnerClass에 method4 메서드를 추가하고 method4 메서드를 SyncBlock의 세 가지 메서드와 동기화합니다. 코드는 다음과 같습니다.
내부 클래스의 비정적 메서드와 외부 클래스의 비정적 메서드 동기화
다음과 같이 코드 코드를 복사합니다.
공개 클래스 SyncBlock
{
… …
클래스InnerClass
{
공개 무효 메소드4()
{
동기화됨(SyncBlock.this)
{
… …
}
}
}
… …
}
위 SyncBlock 클래스의 새 버전에서는 InnerClass 클래스의 메서드 4 메서드가 SyncBlock 클래스의 다른 세 가지 메서드와 동기화되므로 method1, method2, method3 및 method4의 네 가지 메서드 중 하나만 실행할 수 있습니다. 동시.
동기화된 블록이 정상적으로 실행되거나 프로그램 오류로 인해 동기화된 블록이 비정상적으로 종료되면 현재 동기화된 블록이 보유한 동기화 잠금이 자동으로 해제됩니다. 따라서 동기화된 블록을 사용할 때 동기화 잠금 해제에 대해 걱정할 필요가 없습니다.
2. 정적 클래스 메소드의 동기화
왜냐하면 정적 메소드를 호출할 때 객체 인스턴스가 반드시 생성되는 것은 아니기 때문입니다. 따라서 이를 사용하여 정적 메서드를 동기화할 수는 없지만 정적 메서드를 동기화하려면 Class 개체를 사용해야 합니다. 코드는 다음과 같습니다:
동기화된 블록을 통해 정적 메서드 동기화
다음과 같이 코드 코드를 복사합니다.
공개 클래스 StaticSyncBlock
{
공개 정적 무효 메소드1()
{
동기화됨(StaticSyncBlock.class)
{
… …
}
}
공개 정적 동기화 무효 메소드2()
{
… …
}
}
정적 메서드를 동기화할 때 클래스의 정적 필드 클래스를 사용하여 Class 개체를 가져올 수 있습니다. 위의 예에서는 method1과 method2 중 하나만 동시에 실행할 수 있습니다. 클래스 필드를 사용하여 Class 객체를 가져오는 것 외에도 인스턴스의 getClass 메서드를 사용하여 Class 객체를 가져올 수도 있습니다. 위 예제의 코드는 다음과 같이 수정할 수 있습니다.
getClass 메소드를 사용하여 Class 객체를 가져옵니다.
다음과 같이 코드 코드를 복사합니다.
공개 클래스 StaticSyncBlock
{
공개 정적 StaticSyncBlock 인스턴스;
공개 정적SyncBlock()
{
예 = 이것;
}
공개 정적 무효 메소드1()
{
동기화됨(instance.getClass())
{
}
}
}
위 코드에서 StaticSyncBlock 클래스의 인스턴스는 public static 인스턴스를 통해 획득하고, Class 객체는 이 인스턴스의 getClass 메소드를 통해 획득합니다(클래스의 모든 인스턴스는 getClass 메소드를 통해 동일한 Class 객체를 획득하므로, 인스턴스의 getClass 메소드를 사용할 수 있습니다). Test 클래스의 정적 메서드 메서드와 StaticSyncBlock 클래스의 두 가지 정적 메서드 등 Class 객체를 통해 다양한 클래스의 정적 메서드를 동기화할 수도 있습니다.
Test 클래스의 메서드 메서드는 StaticSyncBlock 클래스의 method1 및 method2 메서드와 동기화됩니다.
다음과 같이 코드 코드를 복사합니다.
공개 수업 테스트
{
공개 정적 무효 메소드()
{
동기화됨(StaticSyncBlock.class)
{
}
}
}
참고: 동기화된 블록 동기화 클래스 메서드를 사용하는 경우 비정적 메서드는 이를 사용하여 동기화할 수 있지만 정적 메서드는 Class 개체를 사용하여 동기화해야 합니다. 그들은 서로 영향을 미치지 않습니다. 물론, 정적 메서드를 동기화하기 위해 비정적 메서드의 Class 개체를 사용할 수도 있습니다. 그러나 이는 비정적 메서드를 동기화하기 위해 정적 메서드에서 사용할 수 없습니다. 이는 동기화된 블록 동기화 클래스 메서드를 사용할 때 주의해야 합니다.