The Beruriah Incident
The Beruriah Incident

Reputation: 3257

Confused on producer-consumer solution (synchronization clarification)

I've been learning about concurrency in Java, and I came across the producer-consumer problem. It's apparently standard, and I've seen a near identical answer in many places.

public synchronized void put(int num){
    while (!empty) {
        try{
            wait(); }
        catch {}
    }

    buffer=num;
    empty=false;
    notify();
}

public synchronized int take(){
    while (empty) {
        try{
            wait(); }
        catch {}
    }

    empty=true;
    notify();
    return buffer;
}

My understanding of synchronized is that it uses an object-wide lock, meaning that threads couldn't be in both put and take. But, both methods wait for the other method. This is where I'm confused: this seems to create deadlock. If thread A goes into put while empty=false, it'll wait. Thread B, however, cannot enter take, because it's synchronized. Therefore empty will be false forever, giving deadlock.

Given how many times I've basically seen this answer, however, it seems like it must be right. What am I understanding wrong?

Thank you!

Upvotes: 3

Views: 691

Answers (1)

Tudor
Tudor

Reputation: 62439

Calling wait will release the lock acquired when entering the method. So if A entered put and called wait, the lock is released and B can then proceed inside take.

From the javadoc:

The current thread must own this object's monitor. The thread releases ownership 
of this monitor and waits until another thread notifies threads waiting on this 
object's monitor to wake up either through a call to the notify method or the 
notifyAll method. The thread then waits until it can re-obtain ownership of the 
monitor and resumes execution. 

Upvotes: 4

Related Questions