- isEmpty(): always returns true
- iterator(): returns an empty iterator in which hasNext() always returns false
- peek(): always returns null
- size(): always return zero.
Now, let’s see how to use SynchronousQueue in details with code examples.BlockingQueue<String> syncQueue = new SynchronousQueue<>();
BlockingQueue<Integer> syncQueue = new SynchronousQueue<>(true);
try { syncQueue.put("Element"); } catch (InterruptedException ie) { ie.printStackTrace(); }This method causes the current thread block until another thread has received the element.
try { String element = syncQueue.take(); } catch (InterruptedException ie) { ie.printStackTrace(); }This method causes the current thread block until another thread has inserted an element.
import java.util.*; import java.util.concurrent.*; /** * A producer that puts elements to a BlockingQueue * * @author www.codejava.net */ public class Producer extends Thread { private BlockingQueue<Integer> queue; public Producer(BlockingQueue<Integer> queue) { this.queue = queue; } public void run() { while (true) { try { queue.put(produce()); } catch (InterruptedException ie) { ie.printStackTrace(); } } } private Integer produce() { Random randomer = new Random(); Integer number = randomer.nextInt(1000); try { Thread.sleep(randomer.nextInt(1000)); } catch (InterruptedException ie) { ie.printStackTrace(); } System.out.println("Producer: created number: " + number); return number; } }As you can see, this producer simply creates random Integer numbers and put them to the queue.And the following code is for the consumer class:
import java.util.concurrent.*; /** * A consumer that takes elements from a BlockingQueue * * @author www.codejava.net */ public class Consumer extends Thread { private BlockingQueue<Integer> queue; public Consumer(BlockingQueue<Integer> queue) { this.queue = queue; } public void run() { while (true) { try { Integer number = queue.take(); consume(number); } catch (InterruptedException ie) { ie.printStackTrace(); } } } private void consume(Integer number) { String message = "Consumer [" + getName() + "]: "; message += " processed number: " + number; System.out.println(message); } }This consumer takes elements from the queue and processes them.And the test program looks like this:
import java.util.concurrent.*; /** * A program tests for producer-consumer using SynchronousQueue * * @author www.codejava.net */ public class SynchronousQueueTest { static final int NUMBER_OF_CONSUMERS = 10; public static void main(String[] args) { BlockingQueue<Integer> syncQueue = new SynchronousQueue<>(); Producer producer = new Producer(syncQueue); producer.start(); Consumer[] consumers = new Consumer[NUMBER_OF_CONSUMERS]; for (int i = 0; i < NUMBER_OF_CONSUMERS; i++) { consumers[i] = new Consumer(syncQueue); consumers[i].start(); } } }As you can see, this test program creates one producer thread and 10 consumer threads - all is sharing an instance of a SynchronousQueue.Run this program you will see something like this:
Producer: created number: 333 Producer: created number: 673 Consumer [Thread-8]: processed number: 333 Consumer [Thread-4]: processed number: 673 Producer: created number: 167 Producer: created number: 949 Producer: created number: 234 Producer: created number: 732 Producer: created number: 307 Producer: created number: 28 Consumer [Thread-4]: processed number: 167 Consumer [Thread-3]: processed number: 28 Producer: created number: 898 Consumer [Thread-9]: processed number: 307 Consumer [Thread-6]: processed number: 732 Consumer [Thread-10]: processed number: 234 Consumer [Thread-8]: processed number: 949 Consumer [Thread-3]: processed number: 898Note that the program runs forever so you must press Ctrl + C to stop it.