Question

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);
}
}
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top