【问题标题】:Implementing busy wait with a pair of flags使用一对标志实现忙等待
【发布时间】:2013-02-02 20:34:01
【问题描述】:

我正在尝试使用 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);
}
}

【问题讨论】:

    标签: busy-waiting


    【解决方案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;
        }
    }
    

    此外,从 ProducerConsumer 类中删除 canUpdatecanUse 写入,并将读取(在条件中)替换为方法。

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

    【讨论】:

    • 谢谢,我认为它与 C 线程中的不同......如果逻辑本身可以防止死锁,那么您不必同步多个线程访问的每个变量(据我记住)。
    猜你喜欢
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 2015-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多