title: Java unisex bathroom
body: <p>I have to solve this problem using Java semaphores, but I have no idea how, and I cannot find any related Java materials. This is how it goes:<br></p>
  <p>There are to kinds of threads: men and women. Both wants to use same resources which quantity is BATHROOM_SIZE. 5 rules:</p>
  <ol>
  <li>Every thread, after signaling need of using resource, should wait until he will be able to use it.</li>
  <li>Prevent situation, when more than BATHOOM_SIZE threads is using resource concurrently.</li>
  <li>Prevent woman and man use bathoom in the same time.</li>
  <li>Threads should use resources concurrently. If there are many threads of one type, up to BATHROOM_SIZE threads should use resource.</li>
  <li>Prevent starvation.</li>
  </ol>
  <h2>Results</h2>
  <h3>Works for:</h3>
  <p>1woman, 1man, 5women, 5men</p>
  <h3>Fails for:</h3>
  <p>5women1men, 5men1women, 2men2women, 5men5women.</p>
  <p>I've been trying to make it work since Monday and now I've run out of ideas.</p>
  <h2>Code</h2>
  <p>So my task is to write <em>Bathroom.java</em> class which implements <em>BathroomInterface</em>:</p>
  <pre><code>public interface BathroomInterface {
  
      public static final int BATHROOM_SIZE = 3; //3 is just example
      void manEnter();
      void manExit();
      void womanEnter();
      void womanExit();
  }
  </code></pre>
  <p>In system there are a number of man and woman threads which work like this:</p>
  <pre><code>for(int i = 0; i &lt; n; i++) {
    bathroom.manEnter();
    //uses bathroom random amount of time
    bathroom.manExit();
  }
  
  for(int i = 0; i &lt; m; i++) {
    bathroom.womanEnter();
    //uses bathroom random amount of time
    bathroom.womanExit();
  }
  </code></pre>
  <p>I also have scheme of <em>Bathroom.java</em> class, I have to extend:</p>
  <pre><code>import java.util.concurrent.Semaphore;
  
  public class Bathroom implements BathroomInterface {
  
      
      private Semaphore mutex = new Semaphore(1, true);
  
      public void womanEnter() {
          mutex.acquireUninterruptibly();
      }
  
      public void womanExit() {
          mutex.release();
      }
  
      public void manEnter() {
          mutex.acquireUninterruptibly();        
      }
  
      public void manExit() {
          mutex.release();
      }
  }
  </code></pre>
  <p>This is what I made so far:</p>
  <pre><code>import java.util.concurrent.Semaphore;
  
  public class Bathroom implements BathroomInterface {
      int manW=0, manU=0, womanW=0, womanU=0; //*U-using, *W-waiting
      private Semaphore mutex = new Semaphore(1, false);
  
      public void womanEnter() {
          womanW++;
          StateChange();
      }
  
      public void womanExit() {
          womanU--;
          mutex.release();
          StateChange();
      }
  
      public void manEnter(){
          manW++;
          StateChange();
      }
  
      public void manExit() {
          manU--;
          mutex.release();
          StateChange();
      }
      
      void StateChange() {
          if(womanU==0 &amp;&amp; manU==0) {
              if(manW&gt;womanW) {
                  while(manW&gt;0 &amp;&amp; manU&lt;BATHROOM_SIZE) {
                      manW--;
                      manU++;
                      mutex.acquireUninterruptibly();
                  }
              }
              else {
                  while(womanW&gt;0 &amp;&amp; womanU&lt;BATHROOM_SIZE) {
                      womanW--;
                      womanU++;
                      mutex.acquireUninterruptibly();
                  }
              }
          }
          if(womanU==0 &amp;&amp; manU&lt;BATHROOM_SIZE) {
              while(manW&gt;0 &amp;&amp; manU&lt;BATHROOM_SIZE) {
                  manW--;
                  manU++;
                  mutex.acquireUninterruptibly();
              }
          }
          if(manU==0 &amp;&amp; womanU&lt;BATHROOM_SIZE) {
              while(womanW&gt;0 &amp;&amp; womanU&lt;BATHROOM_SIZE) {
                  womanW--;
                  womanU++;
                  mutex.acquireUninterruptibly();
              }
          }
      }
  }
  </code></pre>