문제

I am trying to implement a busy waiting mechanism, using 2 flags. I get a deadlock, but just can't understand why... it looks to me as if it should work...

sorry for the long code, That's the shortest I succeeded to make it.

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);
}
}
도움이 되었습니까?

해결책

I recommend that all the logic concerning Buffer should go into that class.

Also, accessing (and modifying) the flags must be protected, if 2 or more have access to it. That's why I put synchronised to the 2 methods.

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

Also, remove the canUpdate and canUse writes from the Producer and Consumer classes, and replace the reads (in the conditons) with the methods.

Also, it would be useful to introduce some Thread.sleep(100) in the waiting loops.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top