2013-09-03 1 views
0

이 코드를 사용해 보았습니다. 그러나 0을 인쇄 한 후에는 아무 것도 인쇄하지 않습니다. 내가 생각하는 잠금 장치로 인해 차단 중입니다.2 스레드를 사용하여 홀수 및 짝수 인쇄?

public class EvenOdd implements Runnable { 
    private Object o = new Object(); 
    private volatile int i = 0; 

    public void run() { 
     try { 
      System.out.println(); 
      if (Thread.currentThread().getName().equals("Even")) { 
       printEven(); 
      } else { 
       printOdd(); 
      } 
     } catch (Exception ee) { 
      ee.printStackTrace(); 
     } 
    } 

    private void printEven() throws InterruptedException { 
     while (true) { 
      synchronized (o) { 
       while (this.i % 2 == 0) { 
        o.wait(); 
       } 
       System.out.println(Thread.currentThread().getName() + i); 
       i++; 
       o.notify(); 
      } 
     } 
    } 

    private void printOdd() throws InterruptedException { 
     while (true) { 
      synchronized (o) { 
       while (this.i % 2 != 0) { 
        o.wait(); 
       } 
       System.out.println(Thread.currentThread().getName() + i); 
       i++; 
       o.notify(); 
      } 
     } 
    } 
} 

내 TestClass에 :

EvenOdd x = new EvenOdd(); 
     new Thread(x,"Even").start(); 
     new Thread(x,"Odd").start(); 

어디에서 잘못입니까? 감사합니다.

추신 :이 질문은 여러 번 묻지 만, 나는 스스로 시도하고 싶습니다.

답변

1

내 생각에 당신입니다;

  • 의 Runnable 하나를 사용하지만 모두 그들이 모두 0
  • printEven의 첫 번째 값이 printOdd은 짝수
기다려야합니다 홀수 광고 기다려야합니다 볼도, 즉 생각

편집 : 방공호 코드를 고정 코드를 실행 한 후, 예상대로

0 
1 

를 인쇄합니다. 홀수/짝수의 첫 번째 검사가 동기화되지 않았으므로 때로는 0과 0이 무작위로 인쇄됩니다.

스레드 누군가가 잠금을 통지하는 1 개 대기 :

+0

테스트 클래스를 추가했습니다. – Raj

+0

@Raj 그래서 한 가지 제안이 적용됩니다. –

+0

내 printEven 메소드에서 말하고 있습니다. 조건을 'while (this.i % 2 == 0) {' – Raj

0

그것은 간단한 교착 상태입니다. 스레드 2는 누군가가 동일한 잠금 장치에 통지 할 때까지 기다립니다.

아무도 o.notify();에 도달하지 않으므로 아무런 변화가 없습니다.

두 스레드가 시작될 때 i은 0이므로 둘 다 먼저 printEven()을 호출합니다. 그런 일이 발생하면 두 스레드는 다음 라운드에서 printOdd()을 호출합니다.

+0

어디서 교착 상태를 제거 할 수 있습니까? – Raj

+0

두 스레드가 모두 첫 번째 printEven() 루프에 있다고 말하는 것입니까? – Raj

+0

예. 큰 종이를 가지고 실의 도표를 그리는 것이 좋습니다. 토큰이나 동전을 사용하여 국가 (누가 자물쇠를 가지고 있는지, 자물쇠를 기다리는 자, 'i'의 가치)를 표현하고 그 과정을 시뮬레이션하십시오. –

0

기본 개념은 하나의 스레드가 실행 중이고 다른 스레드가 실행 중일 때입니다. 스레드가 값을 인쇄하면 다른 스레드가 인쇄 할 때까지 기다려야합니다. 이는 대기/통보 메커니즘을 사용하여 수행됩니다.

Odd 스레드가 값 인쇄를 완료하면 대기 스레드 (Even 스레드)에 알리고 Even 스레드는 실행할 준비가되지만 Odd 스레드가 잠금을 해제 할 때까지 대기합니다. 홀수 스레드는 locker 객체에 대해 wait를 호출하여 잠금을 해제하고 대기 상태로 전환합니다. 이 시점에서, 락커 오브젝트의 락을 기다리고있는 유일한 스레드는 짝수 스레드이며 실행됩니다. 이 과정은 대안으로 계속됩니다.

public class Test { 
    public static void main(String[] args) { 
     Object locker = new Object(); 
     Thread t1 = new Thread(new OddWorker(locker)); 
     Thread t2 = new Thread(new EvenWorker(locker)); 
     t1.start(); 
     t2.start(); 

    } 
} 

class OddWorker implements Runnable { 
    private Object locker; 
    private int number = 1, count = 1; 

    OddWorker(Object locker) { 
     this.locker = locker; 
    } 

    @Override 
    public void run() { 
     synchronized (locker){ 
      do { 
       try { 
        System.out.println(Thread.currentThread().getName() + ": " + number); 
        number += 2; 
        locker.notify(); 
        locker.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } while(++count < 11); 
      locker.notify(); 
     } 
    } 
} 

class EvenWorker implements Runnable { 
    private Object locker; 
    private int number = 2, count = 1; 

    EvenWorker(Object locker) { 
     this.locker = locker; 
    } 

    @Override 
    public void run() { 
     synchronized (locker){ 
      do { 
       try { 
        System.out.println(Thread.currentThread().getName() + ": " + number); 
        number += 2; 
        locker.notify(); 
        locker.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } while(++count < 11); 
     } 
    } 
} 
+0

질문에 대한 답변을 * 구체적으로 * 예상하고 있습니다. 질문에 코드가있는 경우 대답은 해당 코드 자체를 처리해야합니다. –