Reputation: 39
I don't understand my mistake, i will describe it and then i will post my code. From main() i want to run 3 threads (each thread containing a loop for 3 women). I have a method that prints each woman that enters the bathroom and each woman that out.I want to use lock so every 3 women in each thread would be written before the next thread will take place.the out put should be something like this: woman 0 enters the bathroom woman 0 exits the bathroom woman 1 enters the bathroom woman 1 exits the bathroom woman 2 enters the bathroom woman 2 exits the bathroom and then 2 times for each thread. my problem is that only one thread is writing and 2 that didnt reach the lock still waiting after i release the lock. here is my code:(BathRoom class)
private Lock lockW=new ReentrantLock();
public int women_present;
public BathRoom(){
women_present=0;//empty at start
}
public void woman_wants_to_enter (int i) {
lockW.lock();
women_present++;
System.out.println ("Woman " + i + " enters bathroom "); }
public void woman_leaves (int i) {
try {
Thread.sleep (1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println ("Woman " + i + " exits bathroom ");
if((women_present%3)==0){
women_present=0;
lockW.unlock();
} }
This is the Women class:
private int i; /* This identifies the woman. */
private BathRoom bathroom;
public Woman (BathRoom bathroom,int i) {
this.i = i;
this.bathroom = bathroom;
}
public void run () {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep ((long) (500 * Math.random()));
}catch (InterruptedException e) {
e.printStackTrace();
}
bathroom.woman_wants_to_enter (i);
bathroom.woman_leaves (i);
}
}}
Upvotes: 1
Views: 161
Reputation: 667
i took the liberty to modify your code :
package stackoverflow;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class BathRoom {
private Lock lockW=new ReentrantLock();
private Condition c1=lockW.newCondition();
public int women_present;
public BathRoom(){
women_present=0;//empty at start
}
public void woman_wants_to_enter (int i) {
lockW.lock();
while(women_present!=i)
try {
c1.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println ("Woman " + i + " enters bathroom "); }
public void woman_leaves (int i) {
try {
Thread.sleep (1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println ("Woman " + i + " exits bathroom ");
women_present++;
if(women_present==3){
women_present=0;
}
c1.signal();
lockW.unlock();
}
}
class Woman implements Runnable{
private int i; /* This identifies the woman. */
private BathRoom bathroom;
public Woman (BathRoom bathroom,int i) {
this.i = i;
this.bathroom = bathroom;
}
public void run () {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep ((long) (500 * Math.random()));
}catch (InterruptedException e) {
e.printStackTrace();
}
bathroom.woman_wants_to_enter (i);
bathroom.woman_leaves (i);
}
}
}
public class testdummy {
public static void main(String[] args) {
BathRoom b=new BathRoom();
Woman w0=new Woman(b, 0);
Woman w1=new Woman(b, 1);
Woman w2=new Woman(b, 2);
Thread A=new Thread(w0);
Thread B=new Thread(w1);
Thread C=new Thread(w2);
A.start();
B.start();
C.start();
}
}
I have made use of Condition object to synchronize the thread access to the method , its not perfect but it works , hope it will give you thoughts for a better approach.
Upvotes: 1
Reputation: 850
First thread In woman_wants_to_enter(), thread aquires lock() so continues. woman_present is set to 1.
In woman_leaves(), woman_present is still 1 if (1 mod 3 is 1) so the unlock is not called
Second thread enters woman_wants_to_enter() but is waiting for the lock
Upvotes: 0