2009-07-16 1 views
-2
내가 예상 한대로 작동하지 않는 동기화 문제가 있습니다

, 나 또한 휘발성 키워드를 사용하여 시도 :자바 동기화 및 스레드

공유 대상 :

public class ThreadValue { 

    private String caller; 
    private String value; 

    public ThreadValue(String caller, String value) { 
     this.value = value; 
     this.caller = caller; 
    } 

    public synchronized String getValue() { 
     return this.caller + "  " + this.value; 
    } 
    public synchronized void setValue(String caller, String value) { 
     this.caller = caller; 
     this.value = value; 
    } 
} 

스레드 1 :

class CongoThread implements Runnable { 
    private ThreadValue v; 
    public CongoThread(ThreadValue v) { 
     this.v = v; 
    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      v.setValue("congo", "cool"); 
      v.getValue(); 
     } 
    } 
} 

스레드 2 :

class CongoThread implements Runnable { 
    private ThreadValue v; 
    public CongoThread(ThreadValue v) { 
    this.v = v; 

    } 
    public void run() { 
     for (int i = 0; i < 10; i++) { 
      v.setValue("congo", "lame"); 
      v.getValue(); 
     } 
    } 
} 

콜링 클래스 :

class TwoThreadsTest { 
    public static void main (String args[]) { 

     ThreadValue v = new ThreadValue("", ""); 
     Thread congo = new Thread(new CongoThread(v)); 
     Thread libya = new Thread(new LibyaThread(v)); 

     libya.start(); 
     congo.start(); 
    } 
} 

때때로 나는 결코 일어나지 않을한다 "In Libya Thread congo cool" 를 얻을. 난 단지 기대 :
"In Libya Thread libya awesome"
"In Congo Thread congo cool"

내가 그들을 혼합을 기대 해달라고.

+1

어떻게 "리비아 스레드 리비아 굉장한"을 기대할 수 있습니까? 귀하의 프로그램에는 "awesome"이라는 단어가 없습니다. –

답변

1

이 사이

v.setValue("congo", ..); 
v.getValue(); 

그런 다음 물론 두 개의 스레드가 인터레이스 수없는 두 라이너 별도로 getValue에 대한 액세스 및 setValue을 동기화하고 다음 :

  1. 스레드 1은
  2. 스레드에게 값 2 개 세트 스레드 1은 당신이 필요로이 문제를 해결하기 위해 스레드 2

에 의해 설정된 값을 읽어

  • 는 GET을 지키는 일 개 락 객체를 가지고있는 값을 설정/set 함수는 두 스레드를 모두 호출합니다. 이렇게하는 가장 좋은 방법은 set과 get을 수행하는 별도의 동기화 된 메서드를 만드는 것입니다. 그러나 때때로 그것은 바람직하지 않습니다. 이 경우 두 스레드에게 잠금 객체를 제공하십시오. 그것은 단순한 대상입니다. 그런 다음 이들은 동기화 된 블록에서 사용합니다.

    각 스레드의 구현은 다음과 같이하고 싶습니다. 정확히 같은 개체가 필요합니다.

    Object lockObject = new Object(); 
    Thread t1 = new CongroThread(v, lockObject); 
    Thread t2 = new LibyaThread(v, lockObject); 
    
    ... 
    
    class CongoThread implements Runnable { 
        private ThreadValue v; 
        private Object lockObject; 
    
        public CongoThread(ThreadValue v, Object lockObject) { 
        this.v = v; 
        this.lockObject = lockObject, 
        } 
        public void run() { 
         for (int i = 0; i < 10; i++) { 
          synchronized(lockObject) 
          { 
           v.setValue("congo", "lame"); 
           v.getValue(); 
          } 
         } 
        } 
    } 
    
  • 0

    System.out.print 호출을 동기화 했습니까? 동기화하지 않으면 스레드로부터 안전하지만 올바른 순서로 방출하지 않을 수 있습니다.

    synchronzied(System.out) { 
        System.out.print(....); 
        System.out.flush(); 
    } 
    
    1

    당신은 하나의는 어떻게됩니까 setValuegetValue