0

Hi I am doing a project and I have reached a part where I am very stuck. I have tried to search for ways to learn how to write the while loop for a busy wait but I haven't found anything and my code just runs as an infinite loop. Can someone help explain to me how a busy waiting loop should work and help me break out of this infinite loop?

The project wants the following to happen: In the morning, after the student wakes up (it will take a random time) he will head to the bathroom to get ready for a new school day. If the bathroom is already taken, the student takes a break (use yield()) and later on he will wait (use busy waiting) for the bathroom to become available. Students will use the bathroom in a First Come First Serve basis (you can use a Boolean array/vector for having them released in order).

 public class Student implements Runnable 
    {
        private Random rn = new Random();
        private String threadNum;
        private volatile boolean bathroomFull = false;
        private static long time = System.currentTimeMillis();
        private Thread t;


    public Student(String studentID) 
    {
      threadNum = studentID;

      t = new Thread(this, "Student Thread #"+threadNum);
      System.out.println("thread created = " + t);
      // this will call run() function
      t.start();
   }

   public void run() 
   {
       int waitTime = rn.nextInt(4000 - 2000 + 1)+2000;

        System.out.println( "the current time is " + (System.currentTimeMillis() - time) + "and the wait time is: " +waitTime );

         //Student wakes up after random time
        while((System.currentTimeMillis()-time) < waitTime)
       {
          // System.out.println("the remaining sleep time is " + (System.currentTimeMillis()-time));
            ;
       }

      int a = rn.nextInt(4000 - 2000 + 1)+2000;
      try 
      {
          //System.out.println("I'm going to sleep for " +a + " milliseconds");
        Thread.sleep(a);
      } 
      catch (InterruptedException e) 
      {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }

      //this is the busy wait loop where is the bathroom is full then a thread will yield until it is available
    int l = rn.nextInt(10 - 1)+1;
  bathroomFull = true;

      while(bathroomFull)
        {
          for(int j = 0; j < l; j++)
          {
              System.out.println("i am in the bathroom for " + l + "minutes " + Thread.currentThread());
          }
          Thread.yield();
          bathroomFull = false;
          //exitBathroom();

        }
    bathroomFull = true;

This is my main method which allows the user to specify how many student threads they want. And yes i don't understand how to implement the change of the value so that the busy wait while loop can be broken.

 public static void main(String args[]) 
   {
       int numberOfStudents;
       numberOfStudents = Integer.parseInt(JOptionPane.showInputDialog("How many students are there in the university? "));
      // System.out.println("there are " + numberOfStudents);

       for(int i = 0; i < numberOfStudents; i++)
       {   
           new Student(String.valueOf(i+1));
       }
          new Teacher();
   }
mets1993
  • 15
  • 1
  • 4
  • Which loop is infinite and which value is not being changed which would end the loop. AFAICS `bathroomFull ` is always false. – Peter Lawrey Apr 25 '15 at 23:22
  • All your Runnable should do is print `the current time is ...` and a few second later exit. Were you expecting to do something else? – Peter Lawrey Apr 25 '15 at 23:23
  • What about his loop? what do you expect to happen? – Peter Lawrey Apr 25 '15 at 23:28
  • I only see one Thread. What are you suppose to be waiting on? – pathfinderelite Apr 25 '15 at 23:29
  • 1
    @pathfinderelite I suspect it is waiting for someone to change the code so that `bathroomFull = true` somewhere. ;) – Peter Lawrey Apr 25 '15 at 23:31
  • the loop below is what i am supposed to use for busy waiting. The project wants us to create multiple threads and then the threads should enter the bathroom on a FIFO basis. I think the code is getting all of the threads that i create into the bathroom at once because they all print i am in the bathroom. I would like help as to enforce that only 1 thread can be in the bathroom at a time. while(bathroomFull) { System.out.println("i am in the bathroom " +Thread.currentThread()); Thread.yield(); } – mets1993 Apr 25 '15 at 23:32
  • 2
    Please don't post code in comments since it loses its formatting making it unreadable. Instead, post any new code to the bottom of your original question by [editing your question](http://stackoverflow.com/posts/29871812/edit). – Hovercraft Full Of Eels Apr 25 '15 at 23:34
  • I edited the code a little bit and the outcome does look better but can anyone with multithreading experience help me understand if the while loop that i created now is enforcing that only 1 thread can be in the bathroom at a time? – mets1993 Apr 25 '15 at 23:57
  • Don't think volatile boolean is enough, you should use AtomicBoolean where you can compare and set in one step. – maraca Apr 26 '15 at 00:20
  • Added more information to explain why AtomicBoolean, thanks for accepting – maraca Apr 26 '15 at 19:57

1 Answers1

1

Here is a working example of a busy wait. It uses an AtomicBoolean to indicate if the bathroom is occupied or not. Atomic operations are executed in one step, this is important to guarantee thread-safety. We could also use a normal boolean and write compareAndSet ourselves:

private static synchronized boolean compareAndSet(boolean expected, boolean value) {
    if (occupied == expected) { // (1)
        occupied = value; // (2)
        return true;
    } else {
        return false;
    }
}

This is the equivalent (for this example) of the Java implementation. synchronized is needed otherwise it would be possible that two threads succeed the test at (1) before (2) was executed (because those 2 operations aren't atomic) and then two people would go in the bathroom together...

import java.util.concurrent.atomic.AtomicBoolean;

public class Student extends Thread {

    // note the static: there is only one bathroom for all students
    private static AtomicBoolean occupied = new AtomicBoolean(false);

    private String name;

    public Student(String name) {
        this.name = name;
    }

    private void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            System.out.println(name + " wet his/her pants");
        }
    }

    @Override
    public void run() {
        int r = (int)(Math.random() * 5000);
        System.out.println(name + " sleeps for " + r + " ms");
        sleep(r);
        System.out.println(name + " goes to bathroom");
        // ***** busy wait *****
        while (!occupied.compareAndSet(false, true)) {
            System.out.println(name + " takes a break");
            Thread.yield();
            sleep(1000);
        }
        // ***** end (in bathroom) *****
        System.out.println(name + " is in the bathroom");
        sleep(1000);
        occupied.set(false);
        System.out.println(name + " goes to university");
    }

    public static void main(String[] args) {
        new Student("Bob").start();
        new Student("Alice").start();
        new Student("Peter").start();
        new Student("Marcia").start();
        new Student("Desmond").start();
        new Student("Sophia").start();
    }

}

possible output:

Bob sleeps for 2128 ms
Marcia sleeps for 3357 ms
Alice sleeps for 1289 ms
Peter sleeps for 820 ms
Desmond sleeps for 1878 ms
Sophia sleeps for 2274 ms
Peter goes to bathroom
Peter is in the bathroom
Alice goes to bathroom
Alice takes a break
Peter goes to university
Desmond goes to bathroom
Desmond is in the bathroom
Bob goes to bathroom
Bob takes a break
Sophia goes to bathroom
Sophia takes a break
Alice takes a break
Desmond goes to university
Bob is in the bathroom
Sophia takes a break
Alice takes a break
Marcia goes to bathroom
Marcia takes a break
Bob goes to university
Sophia is in the bathroom
Alice takes a break
Marcia takes a break
Sophia goes to university
Alice is in the bathroom
Marcia takes a break
Alice goes to university
Marcia is in the bathroom
Marcia goes to university

maraca
  • 8,468
  • 3
  • 23
  • 45
  • Thanks, your while loop is much better than mine and thanks for the info on atomic boolean, I had never heard of it before. I am going to just use a vector because the professor recommended using one. – mets1993 Apr 26 '15 at 19:23