2016-10-08 4 views
5

동기화는이 코드에서 제대로 작동합니다두 번째 코드에서 동기화가 작동하지 않는 이유는 무엇입니까?

class PrintNumbers { 
     synchronized public void display() { 
      System.out.println("in display"); 
      for (int i = 0; i < 3; i++) { 
       System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.getMessage(); 
       } 
      } 
      System.out.println("out of display"); 
     } 
    } 

    class MyThread implements Runnable { 
     Thread t; 
     PrintNumbers printNumbers; 

     MyThread(PrintNumbers printNumbers, String s) { 
      this.printNumbers = printNumbers; 
      t = new Thread(this,s); 
      t.start(); 
     } 

     public void run() { 
      printNumbers.display(); 
     } 
    } 

    class SyncExample { 
     public static void main(String[] args) { 
      PrintNumbers printNumbers = new PrintNumbers(); 

      new MyThread(printNumbers, "My Thread 1"); 
      new MyThread(printNumbers, "My Thread 2"); 
     } 
    } 

출력 :

in display 
Thread name : My Thread 1 i= 0 
Thread name : My Thread 1 i= 1 
Thread name : My Thread 1 i= 2 
out of display 
in display 
Thread name : My Thread 2 i= 0 
Thread name : My Thread 2 i= 1 
Thread name : My Thread 2 i= 2 
out of display 

하지만이 코드 :

class PrintNumbers { 
     synchronized public void display() { 
      System.out.println("in display"); 
      for (int i = 0; i < 3; i++) { 
       System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.getMessage(); 
       } 
      } 
      System.out.println("out of display"); 
     } 
    } 

    class MyThread implements Runnable { 
     Thread t; 
     PrintNumbers printNumbers; 

     MyThread(String s) { 
      this.printNumbers = new PrintNumbers(); 
      t = new Thread(this,s); 
      t.start(); 
     } 

     public void run() { 
      printNumbers.display(); 
     } 
    } 

    class SyncExample { 
     public static void main(String[] args) { 
      new MyThread("My Thread 1"); 
      new MyThread("My Thread 2"); 
     } 
    } 

출력 :

in display 
Thread name : My Thread 1 i= 0 
in display 
Thread name : My Thread 2 i= 0 
Thread name : My Thread 1 i= 1 
Thread name : My Thread 2 i= 1 
Thread name : My Thread 2 i= 2 
Thread name : My Thread 1 i= 2 
out of display 
out of display 

동기화가 Runnable MyThread와 SyncExample 클래스의 PrintNumbers를 초기화하기 위해 만드는 차이점을 이해할 수 없습니다. 설명 해주십시오.

+0

비 정적 동기화 된 메서드는 'this'에서 동기화됩니다. – tkausl

+0

두 번째로 정적 인'display' 메소드가 필요합니다. 두 개의 객체를 잠그고 있습니다. – passion

+1

PrintNumbers의 차이 오브젝트를 사용 중이고 오브젝트 레벨의 잠금이 있습니다. 그래서 당신은 다른 결과를 얻고 있습니다. – cody123

답변

5

동기화가 Runnable MyThread와 SyncExample 클래스의 PrintNumbers를 초기화하기 위해 만드는 차이점을 이해할 수 없습니다.

아니요. 무엇 않습니다 않습니다 첫 번째 예제에서는 하나PrintNumbers 두 스레드가 공유하는 인스턴스가 있습니다. 그러나 두 번째 예에서는 두 개의 개별 인스턴스 인 PrintNumbers이 각 스레드에 하나씩 있습니다.

은 인스턴스 (synchronized 인스턴스 메서드는 this에서 동기화 됨)와 동기화되므로 인스턴스 내에서 동기화되며 여러 인스턴스에서 동기화되지 않습니다.

두 스레드가 인스턴스를 공유하면 display에 대한 두 번의 호출이 직렬화됩니다. 그러나 스레드가 각각 자신의 인스턴스를 가지고있을 때 display에 대한 두 개의 호출은 별도의 인스턴스에 있으므로 호출의 직렬화가 없기 때문에 중복 될 수 있습니다.

4

두 번째 코드에서 각 스레드마다 고유 한 PrintNumbers 개체가 있으므로 병렬로 작동합니다. 첫 번째에서는 단일 PrintNumbers 개체를 공유하고 동기화 된 방식으로 작업합니다.

추신. 정적이 아닌 메서드의 경우 synchronized은 (클래스의 정적 메서드의 경우) 개체에서 동기화를 수행한다는 것을 기억하십시오.

3

두 경우 모두 제대로 작동합니다. 차이점은 첫 번째 경우에는 동기화 된 단일 개체가 있다는 것입니다. 두 번째로는 두 가지가 있습니다. 그들은 둘 다 단 한번 불려서 완벽하게 동기화됩니다.

synchronized은 개체 사이에서 작동하지 않으며 하나에서만 작동합니다.

관련 문제