2013-02-11 2 views
1

동기화 된 블록과 관련하여 의심의 여지가 있습니다. 난 synchornized 블록의 액세스를 얻을 것이다 만 번째 스레드 우선 동기 블록을 실행할 출력을 같은 하나의 스레드 만이 기대되었다스레드 : 동기화 된 블록

Inside run=>thread 2 
Inside run=>thread 1 
Inside run=>thread 1 
Inside run=>thread 2 
Inside run=>thread 2 
Inside run=>thread 1 
Inside run=>thread 2 
Inside run=>thread 1 
Inside run=>thread 1 
Inside run=>thread 2 

로 : 아래의 코드를 실행 한 후 전 출력 geeting 해요. 개념을 잘못 이해했을 수 있습니까?

package com.blt; 

    public class ThreadExample implements Runnable { 
     public static void main(String args[]) 
     { 


      System.out.println("A"); 
      Thread T=new Thread(new ThreadExample()); 
      Thread T1=new Thread(new ThreadExample()); 
      System.out.println("B"); 
      T.setName("thread 1"); 
      T1.setName("thread 2"); 
      System.out.println("C"); 
      T.start(); 
      System.out.println("D"); 
      T1.start(); 
     } 


    synchronized public void run() 
    { 
     for(int i=0; i<5; i++) 
     { 
      try 
      { 
      System.out.println("Inside run=>"+Thread.currentThread().getName()); 
      Thread.currentThread().sleep(2000); 
      } 
      catch(InterruptedException e) 
      { 
       e.printStackTrace(); 
      } 
      } 
    } 
    } 
+0

하나의 ThreadExample 인스턴스를 생성하고 동일한 인스턴스를 스레드 T의 생성자와 스레드 T1에 모두 전달하십시오. 이는 사람들이 이미 제공 한 답변에서 설명한 이유 때문입니다. – Alderath

답변

4

각 스레드가 서로 다른 개체에서 동기화됩니다. 그렇습니다. 그들은 서로를 잠그지 않을 것입니다. 그러나 더 중요한 것은 Runnable 인터페이스 에 대해 동기화 수정자를 정의하지 않았으므로 (이미 볼 수 있듯이 사용자가 생각한대로 효과가 없다는 의미입니다) Runnable 메서드가 정의되어 있습니다.

public synchronized void someMethod(); 

효과적으로 synchronized(this)를 사용하는 것과 같은 일이다

기억해야 할 중요한 것은 당신이 방법에 동기화 된 수식을 사용하는 경우이다. 두 경우 모두 오브젝트 모니터를 잠그고 있습니다. 오브젝트가 여러 개인 경우 여러 개의 모니터가 있습니다.

다음은 예상 한대로 더 많은 작업을 수행하는 예를 수정 한 것입니다.

public class ThreadExample implements Runnable { 
    public static void main(String args[]) { 
     System.out.println("A"); 
     Thread T = new Thread(new ThreadExample()); 
     Thread T1 = new Thread(new ThreadExample()); 
     System.out.println("B"); 
     T.setName("thread 1"); 
     T1.setName("thread 2"); 
     System.out.println("C"); 
     T.start(); 
     System.out.println("D"); 
     T1.start(); 
    } 

    public void run() { 
     synchronized (ThreadExample.class) { 
      for (int i = 0; i < 5; i++) { 
       try { 
        System.out.println("Inside run=>" 
          + Thread.currentThread().getName()); 
        Thread.sleep(500); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 
} 
1

당신은 ThreadExample 두 객체를 생성 한 각각의 스레드는 다른 synchronized 방법이 있습니다 동기화가 예상대로 작동하도록이, (이 경우 클래스 자체를) 공통의 객체 모니터를 사용합니다.

는 동기화 효과를 볼 수 있습니다, 하나의 객체를 생성하고 스레드에 대한 참조를 전달합니다. :) 여기

ThreadExample thex = new ThreadExample(); 
Thread T=new Thread(thex); 
Thread T1=new Thread(thex); 

두 스레드가 같은 synchronized 방법을 사용합니다.

3

두 개의 동기화 된 블록이 동일한 모니터에 을 잠그지 않으면 상호 배타적이지 않습니다..

this 모니터에 동기화 방법 잠금이 기억 - 당신의 코드가 동일합니다 : 당신이 ThreadExample의 두 인스턴스를 만들 수 있기 때문에

public void run() { 
    synchronized(this) { 
     //your code here 
    } 
} 

는 각각 별개의 this 있습니다.

당신은 예를 들어, 두 스레드에서 같은 잠금 장치를 사용하여 문제를 해결할 수 있습니다 :

public void run() { 
    synchronized(ThreadExample.class) { 
     //your code here 
    } 
} 

또는 더 나은, Quoi에 의해 지적 밖으로 같은 ThreadExample 단 하나 개의 인스턴스를 만듭니다.

0

어, 각 스레드의 실행 메소드를 동기화하고 있습니다. Thread1은 Thread2의 run 메소드와 viceversa를 실행하지 않습니다. 이것이 전혀 동기화되지 않는 것과 실질적으로 동일한 이유입니다.

0

클래스의 두 인스턴스를 만들고 클래스에서 동기화 중이므로 공통 잠금이 없으므로 클래스가 독립적으로 실행됩니다. 그들은 따로 달리기를 계속할 것이다.