[concurrency-interest] Strange behavior with LinkedBlockingQueue

Jean Morissette jean.morissette666@videotron.ca
Tue, 26 Oct 2004 18:57:17 -0400


Hi,
I have written a Producer/Consumer test case that show, *almost* always, 
a weird behavior (maybe a deathlock) with the use of 
LinkedBlockingQueue.  Sometime, the test never finish!  Try it please 
and give me your advice.  I am missing something?
Jean

public class ProducerConsumerQueueTest {

   static Object NULL_OBJECT = new Object() {};
   static int i;
   static long time;

   static class Producer implements Runnable {
     BlockingQueue queue;

     Producer(BlockingQueue q) { queue = q; }

     public void run() {
       while(true) {
         try {
           queue.put(NULL_OBJECT);
         } catch (Exception e) {
           e.printStackTrace();
         }
       }
     }
   }

   static class Consumer implements Runnable {
     private BlockingQueue queue;

     Consumer(BlockingQueue q) { queue = q; }

     public void run() {
       int count = 0;
       ArrayList l = new ArrayList(1000);
       while(true) {
         try {
           count = queue.drainTo(l);
           for (int i = 0; i < count; i++) {
             consume(l.get(i));
           }
           System.out.println("count = " + count);
           if (count > 0)
             l.clear();
           else
             Thread.yield();
         } catch (Exception e) {
           e.printStackTrace();
         }
       }
     }

     void consume(Object x) {
       i++;
       if (i % 100 == 0)
         System.out.println("i = " + i);
       if (i >= 1000000) {
         System.out.println("time = "
             + (System.currentTimeMillis() - time)
             + " (ms)");
         System.exit(0);
       }
     }
   }

   public static void main(String args[]) throws InterruptedException {
     time = System.currentTimeMillis();
     BlockingQueue q = new LinkedBlockingQueue();
     Producer p = new Producer(q);
     Consumer c = new Consumer(q);
     Thread t = new Thread(p);
     t.setPriority(Thread.NORM_PRIORITY);
     Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
     t.start();
     c.run();
   }
}