demianr
demianr

Reputation: 39

Lock with 3 threads

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

Answers (2)

Roshan
Roshan

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

Sanj
Sanj

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

Related Questions