title: Multiple read writes on a single static integer index causes index to go out of bounds
body: <p>I was trying to learn multi threading, and was trying out a simple producer/consumer pattern with wait and notify. When i split the pattern with two consume and one produce i get an ArrayIndexOutOfBounds Exception which is not clear. The issue does not occur always it occurs at times. I am using a I3 processor.</p>
  
  <p>I have tried added an if block to check if the count variable is going below or above the declared size and still the issue persists. </p>
  
  <pre><code>
      private static Object key = new Object();
      private static int[] buffer;
      private volatile static Integer count;
  
      static class Consumer {
  
          void consume() {
              synchronized (key) {
                  if (isEmpty()) {
                      try {
                          key.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  buffer[--count] = 0;
                  key.notify();
              }
          }
  
          public boolean isEmpty() {
              return count == 0;
          }
      }
  
      static class Producer {
  
          void produce() {
              synchronized (key) {
                  if (isFull()) {
                      try {
                          key.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  buffer[count++] = 1;
                  key.notify();
              }
          }
  
          public boolean isFull() {
              return count == buffer.length;
  
          }
      }
      public static void main(String[] args) throws InterruptedException {
          buffer = new int[10];
          count = 0;
          Producer producer = new Producer();
          Consumer consumer = new Consumer();
          Runnable produce = () -&gt; {
              for (int i = 0; i &lt; 1500; i++)
                  producer.produce();
              System.out.println("Done producing");
          };
          Runnable consume = () -&gt; {
              for (int i = 0; i &lt; 1300; i++)
                  consumer.consume();
              System.out.println("Done consuming");
          };
          Thread producerWorker = new Thread(produce);
          Thread consumerWorker = new Thread(consume);
          producerWorker.start();
          consumerWorker.start();
          //consumerWorker.join();
          Runnable checker = () -&gt; {
              System.out.println("Lanched Delayed Consumer");
              for (int i = 0; i &lt; 200; i++)
                  consumer.consume();
          };
          Thread delayedConsumer = new Thread(checker);
          delayedConsumer.start();
          producerWorker.join();
          System.out.println("Data in Buffer " + count);
      }
  
   }
  </code></pre>
  
  <p>Expected it to be :</p>
  
  <p>Lanched Delayed Consumer<br>
  Done consuming<br>
  Done producing<br>
  Data in Buffer 0</p>
  
  <p>but got :</p>
  
  <pre><code>Lanched Delayed Consumer
  Exception in thread "Thread-1" Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
      at com.multi.thread.waitandnotify.WaitNotifyRunner$Consumer.consume(WaitNotifyRunner.java:27)
      at com.multi.thread.waitandnotify.WaitNotifyRunner.lambda$1(WaitNotifyRunner.java:78)
      at java.base/java.lang.Thread.run(Thread.java:835)
  java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
      at com.multi.thread.waitandnotify.WaitNotifyRunner$Producer.produce(WaitNotifyRunner.java:55)
      at com.multi.thread.waitandnotify.WaitNotifyRunner.lambda$0(WaitNotifyRunner.java:73)
      at java.base/java.lang.Thread.run(Thread.java:835)
  Data in Buffer 0
  </code></pre>