2013-10-22 4 views
1

Java에서 간단한 대기/통지 예제로 작업 중이므로 어떤 이유로 든 제대로 실행하지 못했습니다. 누구든지이 문제가 무엇인지 알 수 있다면 매우 감사하겠습니다!Java 대기/통지 작동하지 않음

public class ThreadDemonstration 
{ 
private String str = null; 

Thread stringCreator = new Thread(new Runnable() 
{ 
    public void run() 
    {   
     synchronized(this) 
     {    
      str = "I have text"; 
      notify();    
     } 
    } 
}); 

private Thread stringUser = new Thread(new Runnable() 
{ 
    public void run() 
    { 
     synchronized(this) 
     { 
      if(str == null) 
      {     
       try { 
        System.out.println("str is null, I need help from stringCreator"); 
        wait(); 
        System.out.println(str); 
       } 
       catch (InterruptedException e) 
       { 
        e.printStackTrace(); 
       } 
      } 

     } 
    } 
}); 

public static void main (String [] args) 
{ 
    ThreadDemonstration td = new ThreadDemonstration(); 
    td.stringUser.start(); 
    td.stringCreator.start(); 
} 

은}

내 전류 출력은 다음과 같습니다 STR가 null, 내가 그래서 어떤 이유로 스레드 stringCreator가 stringUser 일어나하지 않거나 내가 놓친 거지

stringCreator의 도움이 필요합니다 완전히 다른 것?

감사합니다.

+1

''새 Runnable() {...}'에서 'this'의 가치는 무엇이라고 생각하십니까? – Pshemo

+0

감사합니다. –

답변

4

블록이 다른 개체에 대해 synchronized입니다. 동기화를위한 별도의 객체를 생성 방지하기 위해

public class ThreadDemonstration 
{ 
private String str = null; 
    private final Object monitor = new Object(); 

Thread stringCreator = new Thread(new Runnable() 
{ 
    public void run() 
    {   
     synchronized(monitor) 
     {    
      str = "I have text"; 
      monitor.notify();    
     } 
    } 
}); 

private Thread stringUser = new Thread(new Runnable() 
{ 
    public void run() 
    { 
     synchronized(monitor) 
     { 
      while(str == null) //changed from if to while. This allows you to wait again if the thread gets woken up by something other than the appropriate notify. 
      {     
       try { 
        System.out.println("str is null, I need help from stringCreator"); 
        monitor.wait(); 
        //removed print statement from here 
       } 
       catch (InterruptedException e) 
       { 
        e.printStackTrace(); 
       } 
      } 
      System.out.println(str); //added print statement here. str is guaranteed to not be null here. 
     } 
    } 
}); 

, 당신은 예를 들어 synchronized(ThreadDemonstration.this) 또는 synchronized(ThreadDemonstration.class)를 사용할 수 있습니다 그들은 아래의 예를 들어 monitor 객체, 일반 객체 위에 synchronized해야한다.

+0

감사합니다. 그에 따라 예제를 업데이트했습니다. – Piovezan

+0

대성공! Piovezan 감사합니다! :-) –

+0

아직도 이것이 확실하지 않다. 'StringCreator'가 먼저 잠금을 얻으면'str'을 설정 한 다음'notify()'를 설정합니다. 'StringUser'가 잠금을 얻을 때'str'은 null이 아니므로'wait()'(좋음)는 아니지만'str'을 전혀 출력하지 않습니다. – Cruncher

1

이 시도 :

private Thread stringUser = new Thread(new Runnable() { 
    //----- 

    System.out.println("str is null, I need help from stringCreator"); 
    notify(); 
    wait(100); 
    System.out.println(str); 

    //---- 
}); 
+0

더 나은 서식 지정을 위해 코드 블록에 코드를 추가하는 것을 잊지 마십시오. –

+0

이 코드에는 1 개의 열린 중괄호와 3 개의 닫는 중괄호가 있습니다. – Cruncher

0

당신은 그것이 작동하기 위해서는 동일한 인스턴스의 waitnotify를 사용해야합니다. 두 개의 서로 다른 객체 (2 인스턴스 Runnable)를 만들면 작동하지 않습니다. 본질적인 잠금을위한 메인 클래스의 인스턴스를 사용하는 두 개의 다른 클래스를 사용하는 간단한 예제를 작성했습니다. 또한 이것을 위해 우리는 '더미 객체'(Object lock = new Object)를 사용할 수 있습니다.

public class ThreadDemonstration { 

    private static String text; 

    public ThreadDemonstration(){ 
     Thread user = new Thread(new StringUser(this)); 
     Thread creator = new Thread(new StringCreator(this)); 
     user.start(); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     creator.start(); 
    } 

    public class StringCreator implements Runnable{ 

     private Object lock; 

     StringCreator(Object lock){ 
      this.lock = lock; 
     } 

     @Override 
     public void run() { 
      synchronized(lock){ 
       text = "Yeeeehaaaaa"; 
       lock.notify(); 
      } 

     } 

    } 

    public class StringUser implements Runnable{ 

     private Object lock; 

     StringUser(Object lock){ 
      this.lock = lock; 
     } 

     @Override 
     public void run() { 

      synchronized(lock){ 

       if((text == null)){ 
        System.out.println("I need help!"); 
        try { 
         lock.wait(); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
       System.out.println(text); 
      } 

     } 

    } 

    public static void main(String[] args){ 
     new ThreadDemonstration(); 
    } 

}