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);
}
}
4

1 に答える 1

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;
    }
}

また、 andクラスからcanUpdateandcanUse書き込みを削除し、(条件内の) 読み取りをメソッドに置き換えます。ProducerConsumer

Thread.sleep(100)また、待機ループにいくつか導入すると便利です。

于 2013-02-02T20:43:03.643 に答える