2013-03-31 2 views

답변

6

Foo.class 개체의 모니터에 입력됩니다. 다른 메서드가 Foo.Class에서도 동기화되면 다른 스레드에 있다고 가정하고 대기해야합니다.

메서드가 동기화되지 않으면 정적인지 여부에 관계없이 메서드가 영향을받지 않습니다. 동기화 된 정적 메서드가 정의 된 클래스의 클래스 개체에 대해 암시 적으로 동기화되지는 않습니다.

0

그것은 그것을 사용하는 methods/synchronized 절에 대한 액세스를 동기화합니다. 이것들은 Class Bar의 메소드 일 수 있습니다. Foo 일 필요는 없습니다.

중요한 것은 "Foo.class"에서 동기화되는 모든 메소드/동기화 된 조항이 동시에 실행에서 제외된다는 것입니다.

동기화는 필드에 전혀 영향을 미치지 않습니다. 필드 동기화를 선언 할 방법이 없습니다.

-1

제 생각에 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"); 
    } 
} 

.

+0

아무 멤버도 잠글 수 없습니다. 전혀 아무것도 잠그지 않습니다. 클래스 객체에 * 동기화 *합니다. – EJP

1

클래스 개체의 동기화는 인스턴스 동기화와 동일하게 작동합니다. 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에서는 중괄호 끝 부분 }).

관련 문제