programing

Java 동기 스태틱메서드: 객체 또는 클래스에 대한 잠금

projobs 2022. 10. 21. 21:52
반응형

Java 동기 스태틱메서드: 객체 또는 클래스에 대한 잠금

Java 문서에는 다음과 같이 기재되어 있습니다.

같은 오브젝트상에서 동기화된 메서드의 2개의 호출을 인터리브 할 수 없습니다.

이것은 스태틱 방식에서 무엇을 의미합니까?스태틱 메서드에는 연관된 객체가 없기 때문에 동기화된 키워드는 객체가 아닌 클래스로 잠길까요?

Oscar(매우 간결함!)의 답변에 조금 더 자세히 설명하자면, Java 언어 사양 관련 섹션은 8.4.3.6, '동기화된 메서드'입니다.

동기 방식에서는, 모니터가 실행되기 전에 모니터(θ17.1)를 취득한다.클래스(정적) 메서드의 경우 메서드 클래스의 클래스 개체와 연결된 모니터가 사용됩니다.인스턴스 메서드의 경우 이와 관련된 모니터(메서드가 호출된 개체)가 사용됩니다.

스태틱 메서드에는 연관된 객체가 없기 때문에 동기화된 키워드는 객체가 아닌 클래스로 잠길까요?

네. :)

주의해야 할 한 가지 포인트는 동기화된 스태틱 메서드와 동기화된 비 스태틱 메서드 사이에 링크가 없다는 것입니다.

class A {
    static synchronized f() {...}
    synchronized g() {...}
}

메인:

A a = new A();

스레드 1:

A.f();

스레드 2:

a.g();

f()와 g()는 서로 동기화되지 않으므로 완전히 동시에 실행할 수 있습니다.

다음과 같이 g()를 실장하지 않는 한:

g() {
    synchronized(getClass()) {
        ...
    }
}

이 패턴은 오브젝트의 다른 인스턴스 간에 상호 제외를 구현하고 싶은 경우에도 도움이 됩니다(예를 들어 외부 리소스에 액세스할 때 필요합니다).

내부 잠금동기화에서 Oracle 설명서 페이지를 참조하십시오.

스태틱 메서드는 객체가 아닌 클래스와 관련되어 있기 때문에 스태틱 동기 메서드가 호출되면 어떻게 되는지 궁금할 수 있습니다.이 경우 스레드는 클래스와 관련된 Class 객체의 고유 잠금을 가져옵니다.따라서 클래스의 정적 필드에 대한 액세스는 클래스의 모든 인스턴스에 대한 잠금과는 다른 잠금으로 제어됩니다.

스태틱 메서드에는 관련된 오브젝트도 있습니다.JDK 툴킷의 Class.class 파일에 속합니다..class 파일이 RAM에 로드되면 Class.class는 템플릿오브젝트라고 불리는 파일의 인스턴스를 만듭니다.

예:- 기존 고객 클래스에서 다음과 같은 개체를 생성하려고 할 때

Customer c = new Customer();

Customer.class가 RAM에 로드됩니다.이 때 JDK 툴킷의 Class.class가 Template 객체를 만들고 해당 템플릿 객체에 Customer.class를 로드합니다.Customer.class의 스태틱멤버는 해당 템플릿오브젝트의 속성 및 메서드가 됩니다.

따라서 정적 메서드 또는 Atribute에도 오브젝트가 있습니다.

다음 예에서는 클래스와 오브젝트 잠금을 보다 명확하게 하고 있습니다.아래 예에서는 다른 예에서도 도움이 되었으면 합니다.

예를 들어, 다음 메서드 중 하나는 클래스 취득이고 다른 하나는 객체 잠금 취득입니다.

public class MultiThread {

    public static synchronized void staticLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }

    public synchronized void objLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

따라서 다음과 같은 시나리오를 사용할 수 있습니다.

  1. 동일한 개체를 사용하는 스레드가 액세스를 시도하는 경우objLock 또는 staticLockmethod same time(즉, 두 스레드가 같은 메서드에 액세스하려고 합니다.

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  2. 동일한 개체를 사용하는 스레드가 액세스를 시도하는 경우staticLock그리고.objLockmethods same time(다른 메서드에 대한 접근 제한)

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    
  3. 다른 개체를 사용하는 스레드가 액세스를 시도할 때staticLock방법

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  4. 다른 개체를 사용하는 스레드가 액세스를 시도할 때objLock방법

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    

string class의 경우 string.class에 대해 string.class가 잠기는 등 클래스 객체에 대해 익숙하지 않은 스태틱 동기 메서드는 Java에서 "this" 키워드로 나타나는 객체의 현재 인스턴스에서 잠깁니다.이 두 개체는 서로 다르기 때문에 잠금이 다르기 때문에 한 스레드가 정적 동기 메서드를 실행하는 동안 Java의 다른 스레드는 대신 바이트 .class 리터럴이라고 하는 별도의 잠금을 취득하여 정적 동기 메서드를 시작합니다.

언급URL : https://stackoverflow.com/questions/437620/java-synchronized-static-methods-lock-on-object-or-class

반응형