2013-02-02 3 views
0

2 플래그를 사용하여 통화 대기 메커니즘을 구현하려고합니다. 교착 상태에 빠졌지 만 그 이유는 이해할 수 없습니다 ... 마치 작동해야하는 것처럼 보입니다. ...플래그 쌍을 사용하여 통화 중 대기 구현

미안하지만 긴 코드입니다.

package pckg1; 

public class MainClass { 

public static void main(String[] args) { 
    Buffer b = new Buffer(); 
    Producer prod = new Producer(b); 
    Consumer cons = new Consumer(b); 

    cons.start(); 
    prod.start(); 
} 
} 

class Producer extends Thread { 
private Buffer buffer; 

public Producer(Buffer buffer1) { 
    buffer = buffer1; 
} 

public void run() { 
    for (int i = 0; i < 60; i++) { 
     while (!buffer.canUpdate) 
      ; 
     buffer.updateX(); 
     buffer.canUpdate = false; 
     buffer.canUse = true; 
    } 
} 
} 

class Consumer extends Thread { 
private Buffer buffer; 

public Consumer(Buffer buffer1) { 
    buffer = buffer1; 
} 

public void run() { 
    for (int i = 0; i < 60; i++) { 
     while (!buffer.canUse) 
      ; 
     buffer.consumeX(); 
     buffer.canUse = false; 
     buffer.canUpdate = true; 
    } 
} 
} 

class Buffer { 
private int x; 
public boolean canUpdate; 
public boolean canUse; 

public Buffer() { 
    x = 0; 
    canUpdate = true; 
} 

public void updateX() { 
    x++; 
    System.out.println("updated to " + x); 

} 

public void consumeX() { 
    System.out.println("used " + x); 
} 
} 

답변

1

Buffer과 관련된 모든 로직이 해당 클래스에 포함되어야한다고 권장합니다.

또한 플래그가 2 이상인 경우 플래그에 액세스 (및 수정)해야 보호 할 수 있습니다. 그래서 나는 synchronised을 2 가지 방법에 넣었습니다.

class Buffer { 
private int x; 
private boolean canUpdate; 
private boolean canUse; 

public Buffer() { 
    x = 0; 
    canUpdate = true; 
} 

public synchronised void updateX() { 
    x++; 
    System.out.println("updated to " + x); 
    canUpdate = false; 
    canUse = true; 
} 

public synchronised void consumeX() { 
    System.out.println("used " + x); 
    canUpdate = true; 
    canUse = false; 
} 

    public synchronised boolean canUse() { 
     return canUse; 
    } 
    public synchronised boolean canUpdate() { 
     return canUpdate; 
    } 
} 

는 또한 canUpdatecanUseProducerConsumer 클래스로부터 기록 제거하고,이 방법으로합니다 (conditons에서) 판독 교체한다.

또한 대기 루프에 Thread.sleep(100)을 도입하는 것이 유용 할 수 있습니다.

+0

고마워, 그 C 스레드에서 나는 생각 ... 거기에 논리 자체가 교착 상태를 방지하는 경우 하나 이상의 스레드에 의해 액세스되는 모든 변수를 동기화 할 필요가 없습니다 (만큼 멀리 기억). –