synchronized(Foo.Class){
//some code..
}
Foo 클래스의 모든 인스턴스 또는 고정 메소드/필드 만 잠급니다.동기화 된 (클래스 참조) 기능은 무엇입니까?
synchronized(Foo.Class){
//some code..
}
Foo 클래스의 모든 인스턴스 또는 고정 메소드/필드 만 잠급니다.동기화 된 (클래스 참조) 기능은 무엇입니까?
Foo.class
개체의 모니터에 입력됩니다. 다른 메서드가 Foo.Class
에서도 동기화되면 다른 스레드에 있다고 가정하고 대기해야합니다.
메서드가 동기화되지 않으면 정적인지 여부에 관계없이 메서드가 영향을받지 않습니다. 동기화 된 정적 메서드가 정의 된 클래스의 클래스 개체에 대해 암시 적으로 동기화되지는 않습니다.
그것은 그것을 사용하는 methods/synchronized 절에 대한 액세스를 동기화합니다. 이것들은 Class Bar의 메소드 일 수 있습니다. Foo 일 필요는 없습니다.
중요한 것은 "Foo.class"에서 동기화되는 모든 메소드/동기화 된 조항이 동시에 실행에서 제외된다는 것입니다.
동기화는 필드에 전혀 영향을 미치지 않습니다. 필드 동기화를 선언 할 방법이 없습니다.
제 생각에 tutorialsynchronized(Foo.class) {...}
을 해석하면 클래스의 정적 멤버 만 잠글 것입니다. 그러나 테스트를 작성해야합니다. 작업으로
Task 1 Sleeping
Task 2 Started
T1 A: One
T2 B: Four
T1 B: Two
Task 1 Finished
T2 A: Three
Task 2 Finished
Value A: Three
Value B: Two
작업 한 나는이 정적 잠금이 클래스의 모든 인스턴스를 잠그지 않는다는 것을 보여줍니다 생각 잠금 인스턴스를 유지하는 동안 valueB
2 업데이트 : 출력을 제공
public class SyncTest {
public static SyncTest instance;
public static String valueA;
public String valueB;
public static void main(String[] args) {
instance = new SyncTest();
(new Thread(new Task1())).start();
(new Thread(new Task2())).start();
try {
Thread.sleep(10000);
synchronized(SyncTest.class) {
System.out.println("Value A: " + valueA);
}
synchronized(instance) {
System.out.println("Value B: " + instance.valueB);
}
} catch (InterruptedException interrupt) { }
}
}
class Task1 implements Runnable {
public void run() {
try {
synchronized(SyncTest.class) {
System.out.println("Task 1 Sleeping ");
Thread.sleep(500);
SyncTest.valueA = "One";
System.out.println("T1 A: " + SyncTest.valueA);
}
synchronized(SyncTest.instance) {
Thread.sleep(1000);
SyncTest.instance.valueB = "Two";
System.out.println("T1 B: " + SyncTest.instance.valueB);
}
} catch (InterruptedException interrupt) { }
System.out.println("Task 1 Finished ");
}
}
class Task2 implements Runnable {
public void run() {
System.out.println("Task 2 Started");
try {
Thread.sleep(1000);
synchronized(SyncTest.class) {
SyncTest.instance.valueB = "Four";
System.out.println("T2 B: " + SyncTest.instance.valueB);
Thread.sleep(5000);
SyncTest.valueA = "Three";
System.out.println("T2 A: " + SyncTest.valueA);
}
} catch (InterruptedException interrupt) { }
System.out.println("Task 2 Finished");
}
}
.
아무 멤버도 잠글 수 없습니다. 전혀 아무것도 잠그지 않습니다. 클래스 객체에 * 동기화 *합니다. – EJP
클래스 개체의 동기화는 인스턴스 동기화와 동일하게 작동합니다. Foo.class
과 같은 클래스는 객체이므로 모니터가 내장되어 있습니다. 귀하가 제공 한 코드 :
은 Foo 클래스에 대한 액세스를 동기화합니다. 클래스의 정적 변수를 동기화 할 때 유용 할 수 있습니다. 예를 들면 : 당신이 Foo.class
의 동기화가 인스턴스에 대한로 동일하게 달성 할 수있다 볼 수 있듯이
public class Foo{
private static int COUNTER = 0;
synchronized public static void increment(){
COUNTER ++;
}
public static void decrement(){
synchronized (Foo.class) {
COUNTER ++;
}
}
}
. 인스턴스의 코드 블록을 동기화하려고하면 클래스 객체의 경우 synchronized(Foo.class){}
에 해당하는 synchronized(this){}
이 사용됩니다. 같은 동기화 방법의 경우에 적용 synchronized public void increment(){}
은 동등하다 :
이 푸 클래스의 모든 인스턴스를 고정 않거나 단지 그것을 방법/필드는 정적입니다 : 이제 귀하의 질문에 대한
synchronized public static void increment(){}
?
물론 위에서 설명한대로 모든 인스턴스의 잠금을 획득하지 않습니다. 또한, 클래스 객체는 생성 된 인스턴스를 인식하지 못합니다. synchronized
블록은 필드를 잠그지 않습니다.잠금을 획득 한 스레드에 의해 원자 적 연산으로 강제 실행되는 코드/메소드 블록 만 잠 그어 다른 스레드는 해당 블록을 입력 할 수 없지만 (동기화되지 않으면 다른 블록을 실행할 수 있음) 첫 번째 스레드는 자물쇠를 해제합니다 (Java에서는 중괄호 끝 부분 }
).
@Chandana - 올바르지 않습니다. –