Java의 동기화 된 방법과 동기화 된 블록의 차이점은 무엇입니까? [복제하다
-
18-09-2019 - |
문제
이 질문은 이미 여기에 답이 있습니다.
Java의 동기화 된 방법과 동기화 된 블록의 차이점은 무엇입니까?
나는 인터넷에서 답을 찾고 있었고, 사람들은 이것에 대해 확실하지 않은 것 같습니다 :-(
동기 블록이 범위에서 더 국한 될 수 있으므로 잠금이 더 적은 시간이 될 것이라는 점을 제외하고는 둘 사이에 차이가 없을 것입니다.
그리고 정적 방법에 잠금이있는 경우 잠금 장치는 무엇입니까? 클래스에 잠금의 의미는 무엇입니까?
해결책
동기화 된 메소드는 메소드 수신기를 잠금으로 사용합니다 (즉 this
비 정적 방법 및 정적 방법에 대한 동봉 클래스의 경우). Synchronized
블록은 표현식을 잠금으로 사용합니다.
따라서 다음 두 가지 방법은 잠자리를 잠그는 것과 같습니다.
synchronized void mymethod() { ... }
void mymethod() {
synchronized (this) { ... }
}
정적 방법의 경우 클래스가 잠겨 있습니다.
class MyClass {
synchronized static mystatic() { ... }
static mystaticeq() {
syncrhonized (MyClass.class) { ... }
}
}
동기화 된 블록의 경우 모든 비를 사용할 수 있습니다.null
자물쇠로 개체 :
synchronized (mymap) {
mymap.put(..., ...);
}
잠금 범위
동기화 된 방법의 경우, 잠금은 synchronized
블록, 잠금은 해당 블록 범위 (그렇지 않으면 중요 섹션이라고도 함) 동안 만 유지됩니다. 실제로 JVM은 일부 작업을 제거하여 최적화 할 수 있습니다. synchronized
안전하게 수행 할 수 있음을 증명할 수있는 경우 실행을 차단하십시오.
다른 팁
동기화 된 방법은 속기입니다. 이것:
class Something {
public synchronized void doSomething() {
...
}
public static synchronized void doSomethingStatic() {
...
}
}
모든 의도와 목적을 위해 다음과 같습니다.
class Something {
public void doSomething() {
synchronized(this) {
...
}
}
public static void doSomethingStatic() {
synchronized(Something.class) {
...
}
}
}
(어디에 Something.class
클래스의 클래스 객체입니다 Something
.)
따라서 실제로 동기화 된 블록을 사용하면 잠금에 대해 더 구체적으로 구체적으로 사용할 수 있으며 사용하고 싶을 때 더 세밀하게 입자 할 수 있지만 그 외에는 차이가 없습니다.
예, 그게 한 가지 차이입니다. 다른 하나는 당신이 this
.
주요 차이점은 다음과 같습니다. 동기화 할 메소드를 선언하면 메소드 전체가 동기화됩니다. 그러나 동기화 된 블록을 사용하는 경우 동기화 된 블록의 메소드의 "중요 섹션"만 둘러싸고 나머지 메소드를 블록 밖으로 나눌 수 있습니다.
전체 방법이 중요한 섹션의 일부라면 효과적으로 차이가 없습니다. 그렇지 않은 경우 중요 섹션 주위에 동기화 된 블록을 사용해야합니다. 동기화 된 블록에 더 많은 진술을할수록 전체 병렬 처리가 줄어들므로 최소값을 유지하려고합니다.
객체 인스턴스의 동기화 된 메소드 잠금 메소드가 포함되어 있습니다.
동기화 된 블록으로서 모든 객체에서 잠글 수있는 경우 - 일반적으로 인스턴스 변수로 정의 된 뮤텍스 전환. 이를 통해 잠금 장치가 작동하는 내용을 더 많이 제어 할 수 있습니다.
동기 블록이 범위에서 더 국한 될 수 있으므로 잠금이 더 적은 시간이 될 것이라는 점을 제외하고는 둘 사이에 차이가 없을 것입니다.
예. 당신이 맞습니다. 같지 않은 synchronized
메소드, 동기화 된 문은 고유 잠금을 제공하는 객체를 지정해야합니다.
Java 튜토리얼의 예 :
public void addName(String name) {
synchronized(this) {
lastName = name;
nameCount++;
}
nameList.add(name);
}
동기화 된 명령문은 또한 세밀한 동기화와 동시성을 향상시키는 데 유용합니다. 아래 사용 사례에 대한 동일한 튜토리얼 페이지에서 좋은 예제를 찾을 수 있습니다.
예를 들어 클래스라고 가정 해 봅시다 MsLunch
함께 사용되지 않는 두 개의 인스턴스 필드 인 C1 및 C2가 있습니다. 이 필드의 모든 업데이트는 있어야합니다 synchronized
, 그러나 C1의 업데이트와 함께 C1의 업데이트가 인터리브되는 것을 막을 이유가 없으며, 그렇게하면 불필요한 차단을 만들어 동시성이 줄어 듭니다. 동기화 된 방법을 사용하거나 이와 관련된 잠금 장치를 사용하는 대신 잠금을 제공하기 위해 두 개 객체 만 생성합니다..
그리고 정적 방법에 잠금이있는 경우 잠금 장치는 무엇입니까? 클래스에 잠금의 의미는 무엇입니까?
이 경우 스레드는 클래스와 관련된 클래스 객체에 대한 고유 잠금을 획득합니다. 따라서 클래스의 정적 필드에 대한 액세스는 클래스의 모든 인스턴스에 대한 잠금 장치와는 별개의 잠금으로 제어됩니다.
방법을 만들 때 동기화 (비 static
) :
두 번의 호출에는 불가능합니다 synchronized
동일한 물체에 연락하는 메소드. 한 스레드가 객체에 대한 동기화 된 메소드를 실행하는 경우, 첫 번째 스레드가 객체와 함께 수행 될 때까지 동일한 객체 블록 (SPENTEND EXECUTION)에 대해 동기화 된 메소드를 호출하는 다른 모든 스레드.
방법을 사용하는 경우 static synchronized
:
두 번의 호출에는 불가능합니다 static synchronized
동일한 클래스의 다른 객체에 대한 메소드 인터 리브. 하나의 스레드가 실행될 때 static synchronized
클래스 A의 객체, 호출하는 다른 모든 스레드를위한 메소드 static synchronized
메소드 실행을 통해 첫 번째 스레드가 수행 될 때까지 클래스 A 블록의 모든 객체 (edend execution)의 메소드.
이 SE 질문에서 동기화에 대한 더 나은 대안을 찾을 수 있습니다.