Programing

다른 동기화 된 메서드에서 동기화 된 메서드를 호출하는 것이 안전합니까?

lottogame 2020. 10. 15. 07:22
반응형

다른 동기화 된 메서드에서 동기화 된 메서드를 호출하는 것이 안전합니까?


동기화 된 메서드가 다른 동기화 된 메서드를 호출하는 경우 스레드로부터 안전합니까?

void synchronized method1() {
     method2()
}

void synchronized method2() {
}

예, 메소드를으로 표시 synchronized하면 실제로 다음을 수행하는 것입니다.

void method1() {
    synchronized (this) {
        method2()
    }
}

void method2() {
    synchronized (this) {
    }
}

스레드 호출이 method1에서 method2로 들어 오면 this이미 잠금을 유지 한 다음 통과 할 수 있는지 확인합니다 .

스레드가 method1 또는 method2로 직접 들어가면 잠금 ( this)을 얻을 수있을 때까지 차단 된 다음 진입합니다.

James Black이 주석에서 언급했듯이 메서드 본문 내에서 수행하는 작업에 대해 알고 있어야합니다.

private final List<T> data = new ArrayList<T>();

public synchronized void method1() {
    for (T item : data) {
        // ..
    }
}

public void method3() {
    data.clear();
}

동기화되어 스레드 B가에서 작업하는 동안 스레드 A가 호출 할 수 ConcurrentModificationException있기 때문에 미래 에 a 보고 있기 때문에 갑자기 스레드로부터 안전하지 않습니다 .method3method1


동기화 된 호출 다른 동기화 된 메서드 스레드로부터 안전한 것으로 표시된 메서드입니다.

일반적으로 말할 수 없습니다. 메서드가 수행하는 작업과 동일한 클래스 및 다른 클래스의 다른 메서드가 수행하는 작업에 따라 다릅니다.

그러나 다른 스레드에서 만든 동일한 객체에 대한 method1 및 method2에 대한 호출이 동시에 실행되지 않도록 할 수 있습니다. 메서드가 수행하는 작업에 따라 클래스가 이러한 메서드와 관련하여 스레드로부터 안전하다고 말하기에 충분할 있습니다.


Java Tutorials 사이트 http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html에서

  1. 동일한 개체에서 동기화 된 메서드를 두 번 호출하는 것은 인터리브 할 수 없습니다. 한 스레드가 개체에 대해 동기화 된 메서드를 실행할 때 첫 번째 스레드가 개체에 대해 완료 될 때까지 동일한 개체 블록에 대해 동기화 된 메서드를 호출하는 다른 모든 스레드 (실행 일시 중지)입니다.

  2. 동기화 된 메서드가 종료되면 동일한 개체에 대한 동기화 된 메서드의 후속 호출과 사전 발생 관계를 자동으로 설정합니다. 이렇게하면 개체의 상태 변경 사항이 모든 스레드에 표시됩니다.

따라서 Java는 두 스레드가 동일한 메서드를 실행하는 경우 메서드가 동시에 실행되지 않고 차례로 실행되도록합니다.

하지만 Liveness 문제를 알고 있어야합니다. http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html

또한 불필요하게 잠그고 있는지 여부에 관계없이 전체 개체를 잠그는 코드를 사용 하여 개체가 하나의 변수에 대한 동기화 액세스 만 필요하면 해당 변수를 잠 가야합니다.

참고 URL : https://stackoverflow.com/questions/5798637/is-it-safe-to-call-a-synchronized-method-from-another-synchronized-method

반응형