title: Why this ReadWriteLock example dosen't work?
body: <p><code>LinkedList</code> throws exception when trying to poll data. But I think i correctly use read/write lock concept. What is wrong with that code?</p>
  
  <pre><code>package sample;
  
  import java.util.ArrayList;
  import java.util.LinkedList;
  import java.util.List;
  import java.util.Queue;
  import java.util.concurrent.ArrayBlockingQueue;
  import java.util.concurrent.ConcurrentLinkedQueue;
  import java.util.concurrent.locks.Lock;
  import java.util.concurrent.locks.ReadWriteLock;
  import java.util.concurrent.locks.ReentrantReadWriteLock;
  
  
  public class PingPong extends Thread {
      boolean read = false;
      Queue&lt;String&gt; queue;
      static ReadWriteLock lock = new ReentrantReadWriteLock();
      final static Lock readLock = lock.readLock();
      final static Lock writeLock = lock.writeLock();
      boolean stop;
  
      public PingPong(boolean read, Queue&lt;String&gt; queue) {
          this.read = read;
          this.queue = queue;
      }
  
      int count = 0;
  
      @Override
      public String toString() {
          return "PingPong{" +
                  "read=" + read +
                  ", count=" + count +
                  '}';
      }
  
      @Override
      public void run() {
          if (read) {
              while (!stop) {
  
                  readLock.lock();
  //                synchronized (queue) {
                  try {
  
                      String string = queue.poll();
                      if (string != null) {
                          count++;
                      }
                  } finally {
                      readLock.unlock();
                  }
  
  
  //                }
                  inform();
              }
          } else {
              while (!stop) {
  
                  writeLock.lock();
  //                synchronized (queue) {
                  try {
                      if (queue.add("some str" + count)) {
                          count++;
                      }
                  } finally {
                      writeLock.unlock();
                  }
  
  //                }
  
                  inform();
              }
  
          }
  
  
      }
  
      private void inform() {
  //        Thread.yield();
  //        synchronized (queue) {
  //            queue.notify();
  //            try {
  //                queue.wait(1);
  //            } catch (InterruptedException e) {
  //                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
  //            }
  //        }
      }
  
      public static void main(String[] args) throws InterruptedException {
          Queue&lt;String&gt; queue = new LinkedList();
  //        queue = new ArrayBlockingQueue&lt;String&gt;(100);
  //        queue = new ConcurrentLinkedQueue&lt;String&gt;();
          List&lt;PingPong&gt; pongs = new ArrayList&lt;PingPong&gt;();
          for (int i = 0; i &lt; 10; ++i) {
              PingPong pingPong = new PingPong(i % 2 == 0, queue);
              pingPong.start();
              pongs.add(pingPong);
          }
          Thread.sleep(1000);
          int sum = 0;
          int read = 0;
          int write = 0;
          for (PingPong pp : pongs) {
              pp.stop = true;
              pp.join();
          }
          for (PingPong pp : pongs) {
              System.out.println(pp);
              sum += pp.count;
              if (pp.read) read += pp.count;
              else write += pp.count;
          }
          System.out.println(sum);
          System.out.println("write = " + write);
          System.out.println("read = " + read);
          System.out.println("queue.size() = " + queue.size());
          System.out.println("balance (must be zero) = " + (write - read - queue.size()));
  
      }
  }
  </code></pre>