2013-02-02 65 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線程中,我認爲...那裏你不必同步每個由多個線程訪問的變量,如果邏輯本身可以防止死鎖(據我記憶)。 –