답변:
정적 메서드에는 연결된 개체가 없으므로 동기화 된 키워드가 개체 대신 클래스에서 잠깁니까?
예. :)
this
인스턴스 메소드에서 얻은 잠금입니다. Oscar를 수정하십시오.
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 ()는 서로 동기화되지 않으므로 완전히 동시에 실행할 수 있습니다.
synchronized (MyClass.class) {...}
.
다음과 같이 g ()를 구현하지 않는 한 :
g() {
synchronized(getClass()) {
...
}
}
이 패턴은 객체의 다른 인스턴스간에 상호 배제를 구현하려는 경우에도 유용합니다 (예 : 외부 리소스에 액세스 할 때 필요함).
getClass()
는 런타임 유형을 리턴합니다 . 클래스를 서브 클래스로 만들면 부모 클래스와 자식 클래스가 다른 잠금에서 동기화됩니다. synchronized(MyClass.class)
모든 인스턴스가 동일한 잠금을 사용하도록해야하는 경우가는 방법입니다.
내장 잠금 및 동기화 에 대한 Oracle 설명서 페이지를 살펴보십시오
정적 메소드가 오브젝트가 아닌 클래스와 연관되어 있기 때문에 정적 동기화 메소드가 호출 될 때 어떤 일이 발생하는지 궁금 할 것입니다. 이 경우 스레드는 class와 연관된 Class 객체에 대한 고유 잠금을 획득합니다 . 따라서 클래스의 정적 필드에 대한 액세스는 클래스의 모든 인스턴스에 대한 잠금과 다른 잠금에 의해 제어됩니다 .
정적 메서드에는 관련 개체도 있습니다. JDK 툴킷의 Class.class 파일에 속합니다. .class 파일이 램에로드되면 Class.class는 템플릿 객체라는 파일의 인스턴스를 만듭니다.
예 :-기존 고객 클래스에서 객체를 만들려고 할 때
Customer c = new Customer();
Customer.class는 RAM으로로드됩니다. 이때 JDK 툴킷의 Class.class는 Template 객체라는 객체를 생성하고 해당 Customer.class를 해당 템플릿 객체에로드합니다. 해당 Customer.class의 정적 멤버는 해당 템플릿 객체의 속성과 메소드가됩니다.
따라서 정적 메소드 또는 속성에도 객체가 있습니다
아래 예제는 클래스와 객체 잠금을 더 명확하게 보여줍니다. 아래 예제는 다른 사람들에게도 도움이되기를 바랍니다. :)
예를 들어 아래의 메소드 중 하나는 acquire 클래스와 다른 acquire 객체 잠금입니다.
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);
}
}
}
이제 우리는 다음과 같은 시나리오를 가질 수 있습니다.
동일한 객체를 사용하는 스레드 가 objLock
OR 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
사용하여 스레드 때 동일한 개체 에 액세스하려고 staticLock
및 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
다른 객체를 사용하는 스레드 가 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
다른 객체를 사용하는 스레드 가 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) 인스턴스 동기화 메소드는 Java에서 "this"키워드로 표시되는 Object의 현재 인스턴스에서 잠 깁니다. 이 두 객체가 다르기 때문에 잠금이 다르기 때문에 한 스레드가 정적 동기화 메소드를 실행하는 동안 java의 다른 스레드는 해당 스레드가 반환 될 때까지 기다릴 필요가 없습니다. 대신 byte .class 리터럴로 표시된 별도의 잠금을 획득하고 입력하십시오. 정적 동기화 방법.