title: Java Synchronized Threads not working as expected
body: <p>The following code does not work as I expect it to:</p>
  
  <pre><code>import java.util.ArrayList;
  import java.util.List;
  import java.util.Random;
  
  class Worker implements Runnable {
  
      public void run() {
          System.out.println("Started.");
          process();
  
      }
      private Random random = new Random();
  
      private Object lock1 = new Object();
      private Object lock2 = new Object();
  
      private static List&lt;Integer&gt; list1 = new ArrayList&lt;Integer&gt;();
      private static List&lt;Integer&gt; list2 = new ArrayList&lt;Integer&gt;();
  
      public void stageOne() {
  
          synchronized (lock1) {
  
              try {
                  Thread.sleep(1);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              list1.add(random.nextInt(100));
          }
  
      }
  
      public void stageTwo() {
  
          synchronized (lock2) {
              try {
                  Thread.sleep(1);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              list2.add(random.nextInt(100));
          }
      }
  
      public void process() {
          for(int i=0; i&lt;1000; i++) {
              stageOne();
              stageTwo();
          }
      }
      public static void show() {
          System.out.println("List1: " + list1.size());
          System.out.println("List2: " + list2.size());
      }
  }
  
  public class JavaTest {
  
      public static void main(String[] args) {
  
          long start = System.currentTimeMillis();
  
          Thread t1 = new Thread(new Worker());
          t1.start();
          Thread t2 = new Thread(new Worker());
          t2.start();
  
          try {
              t1.join();
              t2.join();
          } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
          System.out.println("Completed.");
  
          long end = System.currentTimeMillis();
  
          System.out.println("Time taken: " + (end - start));
  
          Worker.show();
      }
  
  }
  </code></pre>
  
  <p>When I run this program, I expect <code>list1</code> and <code>list2</code> to contain 2000 items each and for the program to take approximately 2000 milliseconds. However, lots of times I get lists less than 2000 items, although it does finish around 2000 milliseconds. Sometimes I even get a <code>ArrayOutOfBounds</code> Exception</p>
  
  <pre><code>Started.
  Started.
  Exception in thread "Thread-1" java.lang.ArrayIndexOutOfBoundsException: 163
      at java.util.ArrayList.add(ArrayList.java:459)
      at Worker.stageOne(JavaTest.java:34)
      at Worker.process(JavaTest.java:53)
      at Worker.run(JavaTest.java:14)
      at java.lang.Thread.run(Thread.java:748)
  Completed.
  Time taken: 2217
  List1: 1081
  List2: 1079
  </code></pre>
  
  <p>I expect that each the locks in <code>stageOne</code> and <code>stageTwo</code> should stop the threads from interfering with each other. But that does not seem to be the case. What is the problem with this code? </p>