title: Java Threads: Using sleep and interrupt rather than wait and notifyAll
body: <p><strong>Scenario</strong> - Trying to achieve the result with <code>sleep()</code> and <code>interrupt()</code>; which 
  would have been otherwise done by <code>wait()</code> and <code>notifyAll()</code></p>
  
  <p><strong>Question -</strong> I know this way is not preferred. Can you guys please let me know what is wrong in doing like this in this below
  scenario.</p>
  
  <p><em>One reason is</em> <code>notifyAll()</code> notify all threads looking for the lock on that object. But with <code>interrupt()</code> 
  we have the invoke interrupt on each waiting thread explicitly.</p>
  
  <p><em>Other reason is</em> that a different thread cannot change the object state. Here the initial thread itself make
  <code>food=true</code> on catching an <code>InterruptedException</code>. But what is wrong with that?</p>
  
  <pre><code>/**
   * Objective of this program:
   * 
   * I was thinking, why can't we achieve the guarded block with Sleep and Interrupt,
   * why only with wait and notify..
   * 
   * Wait releases lock; while Sleep does not . But both suspend the execution. 
   * So if you are synchronizing on the object, then we cannot have the second thread
   * to modify the object state due the lock on the object, and the second thread cannot acquire it.
   * 
   * So I did a explicit interrupt on the first thread.
   * 
   */
  /**
   * 
   * One person ask if he has something to eat polling the "food" variable.
   * Another person updates the shared variable food.
   * 
   * food = true means the first person can start eating. food = false means he
   * has to wait and poll the value until food is available(food = true). This is
   * not a producer-consumer problem.
   * 
   */
  
  public class _17GuardedBlockWithSleep_Interrupt_Badcase {
  
      static class Person {
  
          volatile boolean food;
  
          public boolean isFood() {
              return food;
          }
  
          public void setFood(boolean food) {
              this.food = food;
          }
  
          String name;
  
          Person(String name) {
              this.name = name;
          }
  
          /*
           * Sloppy/Bad way of implementation making it pause execution until it
           * gets interrupted. An interruption alone does not mean food is
           * available. May be interrupt was called by someone else who does not
           * provide food. So check the condition too.
           * 
           * Through sleep(), the execution is paused. CPU is free to take other
           * tasks, The lock on object is NOT released so other threads CANNOT
           * acquire the lock on the object.
           */
  
          // Guarded Block
          public synchronized void eatFood() {
              while (!isFood()) {
                  // food is currently unavailable. I'm waiting..
                  try {
                      /**
                       * Ideally we do wait() and notifyAll() in such a scenario. I am
                       * trying with Sleep and Interrupt.
                       */
                      Thread.sleep(1000000000);
                  } catch (InterruptedException e) {
                      this.setFood(true);// it's not some other thread that provide food. it's itself!
                      System.out.println("eatFood() caught InterruptedException");
                      // e.printStackTrace();
                  }
              }
              // if control comes here, then it means food is available
              System.out.println("got the food.. yummyy..thanks!");
          }
  
          public synchronized void provideFood(Thread t) {
              this.setFood(true); // this refers to current object. In this case, the
                                          // 'kuttappan' object
              // interrupt the first thread
              t.interrupt();
          }
  
      }
  
      public static void main(String[] args) {
          final Person kuttappan = new Person("Kuttappan");
  
          Runnable runnable1 = new Runnable() {
              @Override
              public void run() {
                  /*
                   * if kuttappan is not already defined as final, you get an error
                   * "Cannot refer to a non-final variable kuttappan inside an inner class defined in a different method"
                   */
                  kuttappan.eatFood();
                  /*
                   * thread will try to acquire the lock on 'kuttappan' object when it
                   * invokes the synchronized method.
                   */
              }
          };
          final Thread t = new Thread(runnable1, "thread1");
          t.start();
  
          // someone is needed to make the food available for kuttappan.
  
          new Thread(new Runnable() {
              @Override
              public void run() {
                  try {
                      Thread.sleep(5000); // 5 seconds
                      t.interrupt(); // MY IMPORTANT LINE
                      // kuttappan.provideFood(t);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }).start();
      }
  }
  
  /**
   * OUTPUT:
   * 
   * Observe the line commented as "MY IMPORTANT LINE"
   * 
   * If you do 'kuttappan.provideFood(t);' then the program Keeps on running. no
   * output, because
   * 
   * The second thread cannot get into provideFood() of kuttappan object because
   * the first thread has not released the lock on the object!
   * 
   * But if you do t.interrupt(); the thread is interrupted and the program
   * behaves as expected.
   */
  </code></pre>