A teammate wrote this buffer for EdgeCampus frames. It "works in testing" but occasionally loses frames, occasionally hangs, and once threw an exception.
class FrameBuffer {
private final Frame[] buf = new Frame[64];
private int in = 0, out = 0, count = 0;
public void put(Frame f) throws InterruptedException {
synchronized (this) {
if (count == buf.length) wait();
}
buf[in] = f;
in = (in + 1) % buf.length;
count++;
synchronized (this) { notify(); }
}
public synchronized Frame take() throws InterruptedException {
if (count == 0) wait();
Frame f = buf[out];
out = (out + 1) % buf.length;
count--;
notify();
return f;
}
}
- Find at least four concurrency bugs; for each, give a concrete interleaving or scenario that causes a visible failure (lost frame, hang, exception, wrong frame).
- Rewrite the class correctly using a monitor (
synchronized,wait,notifyAll). - Rewrite it in one line using a class from
java.util.concurrent, and explain when you would still prefer your own implementation.