Reputation: 1115
I'm doing a simple exercise to understand the concept of threads and synchronization. But I don't know whether the code is correct or not.
public class PopcornMachine {
// shared resource
private boolean isBinFull = false;
// producer method
public synchronized void placePopcorn () throws InterruptedException {
while (true) {
while (!isBinFull) wait ();
isBinFull = true;
System.out.println(isBinFull);
notify ();
Thread.sleep(1000);
}
}
// consumer code
public synchronized void takePopcorn () throws InterruptedException {
while (true) {
while (isBinFull) wait ();
isBinFull = false;
System.out.println(isBinFull);
notify ();
Thread.sleep(1000);
}
}
}
public class PopcornDemo {
public static void main (String[] args) throws InterruptedException{
final PopcornMachine machine = new PopcornMachine();
Thread produce = new Thread (new Runnable() {
public void run() {
try {
machine.placePopcorn ();
} catch(InterruptedException e) {}
}
});
Thread consume = new Thread (new Runnable() {
public void run() {
try {
machine.takePopcorn ();
} catch(InterruptedException e) {}
}
});
produce.start();
consume.start();
produce.join();
consume.join();
}
}
The answer I have is: false false false false false false
But it feels wrong. Isn't there a true value should come in the middle of the code?
Upvotes: 0
Views: 314
Reputation: 2002
Change the while
condition like below and look at the comments . With your current code producer never executes.
Why? because isBinFull
set to false initially and set to false in consumer too
and inside your producer code
while (!isBinFull) wait ();
will be never become false
and keep waiting inside while
loop.
Change the code like below
public synchronized void placePopcorn () throws InterruptedException {
while (true) {
while (isBinFull) wait(); //Look here, waiting since bin is full
isBinFull = true;
System.out.println(Thread.currentThread().getName() + ":"+isBinFull);
notifyAll ();
Thread.sleep(500);
}
}
// consumer code
public synchronized void takePopcorn () throws InterruptedException {
while (true) {
while (!isBinFull) wait(); ////Look here, waiting since bin is not full
isBinFull = false;
System.out.println(Thread.currentThread().getName() + ":"+isBinFull);
notifyAll ();
Thread.sleep(500);
}
}
Upvotes: 2
Reputation: 3158
using synchronised
at method level itself makes sure only one thread executes at a time.
synchronised
keyword takes lock
on the object it is being called i.e. machine
in your case and hence the code is not a proper implementation of producer-consumer problem.
Upvotes: 1