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采用这两种方法的原因。

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类中删除canUpdatecanUse写入,并用方法替换读取(在条件中)。ProducerConsumer

Thread.sleep(100)此外,在等待循环中引入一些也会很有用。

于 2013-02-02T20:43:03.643 回答