title: Implementing semaphores in java
body: <p>I have some code that generates threads (lizards)
  it also makes a cat thread.</p>
  
  <p>the cat checks on the lizards (once it wakes up) and if there are to many crossing a path at one time it eats them. the idea is to have the lizards cross and eat  while the world has not 'ended' with out interruption from the cat thread.</p>
  
  <p>I need to use semaphores to control this.</p>
  
  <p>I have the idea down just need that extra push so I can start taking a crack of it.</p>
  
  <p>Ive edited to code to show where my issues are.</p>
  
  <pre><code>import java.util.ArrayList;
  import java.util.concurrent.Semaphore;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  
  
  public class LizardsSync 
  {
      /*
       * Set this to the number of seconds you want the lizard world to
       * be simulated.  
       * Try 30 for development and 120 for more thorough testing.
       */
      private static int WORLDEND = 30;
  
      /*
       * Number of lizard threads to create
       */
      private static int NUM_LIZARDS =20;
  
      /*  
       * Maximum lizards crossing at once before alerting cats
       */
      private static int MAX_LIZARD_CROSSING = 4;
  
      /*
       * Maximum seconds for a lizard to sleep
       */
      private static int MAX_LIZARD_SLEEP_TIME = 3;
  
      /*
       * Maximum seconds for a lizard to eat
       */
      private static int MAX_LIZARD_EAT_TIME = 5;
  
      /*
       * Number of seconds it takes to cross the driveway
       */
      private static int CROSS_TIME = 2;
  
      /*
       * Number of seconds for the cat to sleep.
       */
      private static int MAX_CAT_SLEEP;
  
      /*
       * A counter that counts the number of lizzards crossing sago to monkey grass
       */
      int numCrossingSago2MonkeyGrass = 0;
  
      /*
       * A counter that counts the number of lizzards crossing monkey grass to sago
       */
      int numCrossingMonkeyGrass2Sago = 0;
  
      /**
       * A semaphore to protect the crossway. 
       * only the max amount of lizards can cross so the cat wont 'play'
      */
      Semaphore semaphoreCrossway = new Semaphore(MAX_LIZARD_CROSSING,true);
  
      /**
       * A semaphore for mutual exclusion.
       */
      Semaphore mutex = new Semaphore(4);
  
      // on both semaphores, you can call acquire() or release()
      /*
       * Indicates if the world is still running.
       */
      private static boolean running = true;
  
      /*
       * Indicates if you want to see debug information or not.
       */
      private static boolean debug = true;
  
  
      public void go()
      {
          ArrayList&lt;Thread&gt; allThreads = new ArrayList&lt;Thread&gt;();
  
          // create all the lizzard threads
          for (int i=0; i &lt; NUM_LIZARDS; i++) 
          {       allThreads.add(new LizardThread(i) );
              allThreads.get(i).start();
  }
          // create the cat thread
          Thread CatThread = new CatThread();
           CatThread.start();
  
          // let the world run for a while
          sleep (WORLDEND);
  
          // terminate all threads
          running = false;
          // wait until all threads terminate by joining all of them
          for (int i=0; i &lt; NUM_LIZARDS; i++) {
              try {
                 allThreads.get(i).join();
              } catch (InterruptedException ex) {
                  System.err.println ("unable to join thread, " + ex.getMessage());
              }
          }
      }
         /**
       * @param args the command line arguments
       */
      public static void main(String[] args) {
          // starts the program
          new LizardsSync().go();
      }
  
       /**
       * Models a cat thread.
       */
      public class CatThread extends Thread {
  
  
          /**
           * @see java.lang.Runnable.
           */
          @Override
          public void run() 
          {   
              // you must finish this method
  
              while (running) {
                 // sleep for a while
                 catSleep();
  
                 // check on lizzards
                 checkCrossway();
              }
          }
  
          /**
           * Puts cat thread to sleep for a random time.
           */
          public void catSleep()
          {
              int sleepSeconds  = 1 + (int)(Math.random()*MAX_CAT_SLEEP);
  
              if (debug) {
                  System.out.println ("Cat is sleeping for " + sleepSeconds + " seconds.");
                  System.out.flush();
              }
              try {
                  sleep(sleepSeconds*1000);
              } catch (InterruptedException ex) {
                  Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
              }
              if (debug) {
                  System.out.println ("Cat awakes.");
                  System.out.flush();
              }
          }
  
          /**
           * Simulates cat checking the crossway.
           */
          public void checkCrossway()
          {
              if (numCrossingMonkeyGrass2Sago + numCrossingSago2MonkeyGrass &gt; MAX_LIZARD_CROSSING) {
                  System.out.println ("The cat says yum!");
                  System.out.flush();
                       System.exit(-1);
              }
         }
      }
  
      /**
       * Models a lizard thread.
       */
      public class LizardThread extends Thread {
  
          private int _id;
  
          /**
           * Creates a new lizard thread.
           * 
           * @param id the id assigned to the lizard thread
           */
          public LizardThread(int id)
          {
              _id = id;
          }
  
          /**
           * @see java.lang.Runnable.
           */
          @Override
          public void run() 
          {    
              while (running) {
                 // sleep for a while in sago
                 lizardSleep();
                 // wait until safe to cross from sago to monkey grass
                 sagoToMonkeyIsSafe();
                 // cross path to monkey grass
                 crossedOverToMonkey();
                 // eat in the monkey grass
                 lizardEat();
                 // wait untill its safe to cross back to sago
                 monkeyToSagoIsSafe();
                 // cross from cross monkey grass to sage
                 crossMonkeyToSago();
              }
          }
  
          /**
           * This tests if it is safe to travel from sago to monkey.
           * Finish this.
           */
          public void sagoToMonkeyIsSafe()
          {
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] checks sago -&gt; monkey grass.");
                  System.out.flush();
              }
  
              // you must add code here
              // use a semaphore 
  
  
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] thinks sago -&gt; monkey grass is safe.");
                  System.out.flush();
              }
          }
  
          /**
           * Indicates that lizard crossed over to monkey grass.
           * Finish this.
           */
          public void crossedOverToMonkey()
          {
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] made it to monkey grass.");
                  System.out.flush();
              }
  
              // add code here
          }
  
  
          /**
           * This tests if it is safe to travel from monkey to sago.
           * Finish this.
           */
          public void monkeyToSagoIsSafe()
          {
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] checks monkey grass -&gt; sago.");
                  System.out.flush();
              }
  
              // you must add code here
              // use a semaphore 
  
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] thinks monkey grass -&gt; sago is safe.");
                  System.out.flush();
              }
          }
  
          /**
           * Indicates that lizard crossed over to sago.
           * Finish this.
           */
          public void crossedOverToSago()
          {
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] made it to sago.");
                  System.out.flush();
              }
  
              // add code here
          }
  
          /**
           * Indicates that lizard is crossing over from monkey to sago.
           * Finish this
           */
          void crossMonkeyToSago()
          {
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] is crossing monkey grass to sago.");
                  System.out.flush();
              }
  
              numCrossingMonkeyGrass2Sago++;
  
              // simulate walk
              try {
                  sleep(CROSS_TIME*1000);
              } catch (InterruptedException ex) {
                  Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
              }
  
              numCrossingMonkeyGrass2Sago--;
          }
  
          /**
           * Indicates that lizard is crossing over from sago to monkey. 
           */
          void crossSagoToMonkey()
          {
  
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] is crossing sago to monkey grass.");
                  System.out.flush();
              }
  
              numCrossingSago2MonkeyGrass++;
  
              // simulate walk
              try {
                  sleep(CROSS_TIME*1000);
              } catch (InterruptedException ex) {
                  Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
              }
  
              numCrossingSago2MonkeyGrass--;
          }
  
  
          /**
           * Puts lizard thread to sleep for a random amount of time.
           */
          public void lizardSleep()
          {
              int sleepSeconds  = 1 + (int)(Math.random()*MAX_LIZARD_SLEEP_TIME);
  
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] is sleeping for " + sleepSeconds + " seconds.");
                  System.out.flush();
              }
              try {
                  sleep(sleepSeconds*1000);
              } catch (InterruptedException ex) {
                  Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
              }
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] awakes.");
                  System.out.flush();
              }
          }
  
          /**
           * Simulates lizard eating for a random amount of time.
           */
          public void lizardEat()
          {
              int eatSeconds  = 1 + (int)(Math.random()*MAX_LIZARD_EAT_TIME);
  
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] is eating for " + eatSeconds + " seconds.");
                  System.out.flush();
              }
              try {
                  sleep(eatSeconds*1000);
              } catch (InterruptedException ex) {
                  Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
              }
              if (debug) {
                  System.out.println ("Lizard [" + _id + "] finished eating.");
                  System.out.flush();
              }
          }
      }
  
  
      /**
       * Puts current thread to sleep for a specified amount of time.
       * 
       * @param seconds the number of seconds to put the thread to sleep
       */
      private static void sleep(int seconds)
      {
          try {
              Thread.sleep(seconds*1000);
          } catch (InterruptedException ex) {
              Logger.getLogger(LizardsSync.class.getName()).log(Level.SEVERE, null, ex);
          }
      }
  
  }
  </code></pre>
  
  <p>this code as of now writes something like this</p>
  
  <pre><code>Cat awakes.
  The cat says yum!
  Lizard [8] finished eating.
  Lizard [0] is sleeping for 1 seconds.
  Lizard [8] checks monkey grass -&gt; sago.
  Lizard [1] finished eating.
  Lizard [8] thinks monkey grass -&gt; sago is safe.
  Lizard [1] checks monkey grass -&gt; sago.
  Lizard [8] is crossing monkey grass to sago.
  Lizard [1] thinks monkey grass -&gt; sago is safe.Java Result: -1
  BUILD SUCCESSFUL (total time: 5 seconds)
  </code></pre>