title: stopping threads that run indefinitely
body: <p>I have been trying to implement the producer consumer pattern. If both producer and consumer are running indefinitely how should one try to stop them?</p>
  
  <p>I have been trying to test the status of <code>isInterrupted()</code> but the following code does not guarantee all threads to stop. </p>
  
  <pre><code>public class Monitor {
  
      private int value;
      private boolean readable = false;
  
      public synchronized void setVal(int value) {
          while (readable) {
              try {
                  this.wait();
              } catch (InterruptedException e) {
                  break;
              }
          }
  
          if (!Thread.currentThread().isInterrupted()) {
              this.readable = true;
              this.value = value;
              this.notifyAll();
          }
      }
  
      public synchronized int getVal() {
          while (!readable) {
              try {
                  this.wait();
              } catch (InterruptedException e) {
                  break;
              }
          }
          if (!Thread.currentThread().isInterrupted()) {
              this.readable = false;
              this.notifyAll();
          }
          return this.value;
      }
  }
  </code></pre>
  
  <p>The producer class looks like this:</p>
  
  <pre><code>import java.util.Random;
  
  public class Producer implements Runnable {
  
      private Monitor monitor;
      private Random r = new Random();
      private String name;
  
      public Producer(Monitor m) {monitor = m;}
  
      public void run() {
          name = Thread.currentThread().getName();
          while (!Thread.currentThread().isInterrupted()) {
              int value = r.nextInt(1000);
              monitor.setVal(value);
              System.out.println("PRODUCER: " + name + " set " + value);
          }
          System.out.println("PRODUCER: " + name + " interrupted");
      }
  }
  </code></pre>
  
  <p>The consumer</p>
  
  <pre><code>public class Consumer implements Runnable {
  
      private Monitor monitor;
      private String name;
  
      public Consumer(Monitor m) {monitor = m;}
  
      public void run() {
          name = Thread.currentThread().getName();
          while (!Thread.currentThread().isInterrupted()) {
              int value = monitor.getVal();
              System.out.println("CONSUMER: " + name + " got " + value);
          }
          System.out.println("CONSUMER: " + name + " interrupted");
      }
  }
  </code></pre>
  
  <p>And the main:</p>
  
  <pre><code>public class Main {
  
      public static void main(String[] args) {
  
          final int n = 2;
          Monitor m = new Monitor();
  
          Thread[] producers = new Thread[n];
          Thread[] consumers = new Thread[n];
  
          for (int i = 0; i &lt; n; i++) {
              producers[i] = new Thread(new Producer(m));
              producers[i].start();
              consumers[i] = new Thread(new Consumer(m));
              consumers[i].start();
          }
  
  //        try {
  //            Thread.sleep(1);
  //        } catch (InterruptedException e) {}
  
          for (int i = 0; i &lt; n; i++) {
              producers[i].interrupt();
              consumers[i].interrupt();
          }
      }
  }
  </code></pre>
  
  <p>I get the following results </p>
  
  <pre><code>PRODUCER: Thread-0 set 917
  CONSUMER: Thread-1 got 917
  PRODUCER: Thread-2 set 901
  PRODUCER: Thread-0 set 29
  CONSUMER: Thread-3 interrupted
  CONSUMER: Thread-1 got 29
  CONSUMER: Thread-1 interrupted
  PRODUCER: Thread-2 set 825
  ...program hangs
  </code></pre>
  
  <p>and </p>
  
  <pre><code>PRODUCER: Thread-0 set 663
  CONSUMER: Thread-1 got 663
  PRODUCER: Thread-0 set 129
  CONSUMER: Thread-1 got 129
  PRODUCER: Thread-2 set 93
  PRODUCER: Thread-2 interrupterd
  CONSUMER: Thread-3 interrupted
  PRODUCER: Thread-0 set 189
  PRODUCER: Thread-0 interrupterd
  CONSUMER: Thread-1 got 129
  ...program hangs
  </code></pre>
  
  <p>etc... </p>
  
  <p>There is clearly something wrong. Why am I not registering the calls the <code>interrupt</code> on a consistent basis? </p>