Using a ConcurrentLinkedQueue

A ConcurrentLinkedQueue is an unbounded non-blocking FIFO queue. Although there is already a thread-safe implementation of a linked list:

   List list = Collections.synchronizedList(new LinkedList(...));

the ConcurrentLinkedQueue offers better concurrent performance and scalability.

Main.java:

import java.util.concurrent.*;
import java.util.*;
 
public class Main
{
   public static void main(String []args) {
      Queue<Message> queue = new ConcurrentLinkedQueue<Message>();
 
      Producer p = new Producer(queue);
      new Thread(p).start();
 
      // wait a bit before consuming to allow the queue to fill up
      // and force a blocking wait
      try { Thread.sleep(1000); } catch(InterruptedException e) { }
      Consumer c = new Consumer(queue);
      new Thread(c).start();
   }
}
 
class Producer implements Runnable
{
   private Queue<Message> queue;
 
   public Producer(Queue<Message> queue) {
      this.queue = queue;
   }
 
   public void run() {
      for (int i=0; i<1000; i++) {
         Message<String> m = new Message<String>("message contents #" + i);
         System.out.println("Producing '" + m + "'");
         queue.offer(m);
      }
   }
}
 
class Consumer implements Runnable
{
   private Queue<Message> queue;
    
   public Consumer(Queue<Message> queue) {
      this.queue= queue;
   }
    
   public void run() {
      while (true) {
         Message m = queue.poll();
         if (m != null) {
            System.out.println("tConsuming '" + m + "'");
         }
         else {
            System.out.println("All elements consumed.");
            break;
         }
      }
   }
}
 
class Message<T> {
   private T contents;
    
   public Message(T contents) {
      this.contents = contents;
   }
    
   public T getContents() {
      return contents;
   }
    
   public String toString() {
      return ""+contents;
   }
}