Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Threads 101


Java Solutions June 2001/import java.*/Listing 14

Listing 14: Uses a counter to manage producer and consumer threads

import java.util.*;

class Counter
{
   private int count;

   public Counter()
   {
      count = 0;
   }

   public void increment()
   {
      ++count;
   }

   public void decrement()
   {
      --count;
   }

   public int get()
   {
      return count;
   }
}

class Queue
{
   // The shared buffer:
   static Queue store = new Queue();

   private LinkedList data = new LinkedList();
    
   public void put(Object o)
   {
      data.addFirst(o);
   }
   public Object get()
   {
      return data.removeLast();
   }
   public int size()
   {
      return data.size();
   }
}

class Producer extends Thread
{
   private static Random numbers = new Random();
   private Counter counter;

   Producer(String id, Counter counter)
   {
      super(id);
      this.counter = counter;
   }

   int genNumber()
   {
      // Generate a random number in (0, 1000)
      return (int)(numbers.nextDouble()*1000);
   }

   public void run()
   {
      counter.increment();
      
      // Generate some elements for the Queue
      for (int i = 0; i < 8; ++i)
      {
         int number = genNumber();
         System.out.println(getName() + " producing " + number);
         synchronized(Queue.store)
         {
            Queue.store.put(new Integer(number));
            Queue.store.notify();
         }
      }
      synchronized(Queue.store)
      {
         // Prevent deadlock for multiple consumers
         counter.decrement();
         Queue.store.notifyAll();
      }
      System.out.println("\t" + getName() + " finished");
   }
}

class Consumer extends Thread
{
   private Counter counter;

   Consumer(String id, Counter counter)
   {
      super(id);
      this.counter = counter;
   }

   public void run()
   {
      for (;;)
      {
         synchronized(Queue.store)
         {
            while (Queue.store.size() == 0)
            {
               if (counter.get() == 0)
               {
                  // Producers are done and queue is empty
                  System.out.println("\t" + getName()
                                     + " terminating");
                  return;
               }
               try
               {
                  Queue.store.wait();
               }
               catch (InterruptedException x)
               {}
            }
            System.out.println(getName() + " consuming "
                              + Queue.store.get());
         }
      }
   }
}

class CommTest2
{
   public static void main(String[] args)
   {
      // Start Producers
      Counter counter = new Counter();
      new Producer("Producer1", counter).start();
      new Producer("Producer2", counter).start();

      // Start Consumers
      new Consumer("Consumer1", counter).start();
      new Consumer("Consumer2", counter).start();
   }
}

/* Output:
Producer1 producing 386
Producer1 producing 240
Producer1 producing 982
Producer1 producing 453
Producer1 producing 878
Producer1 producing 228
Producer1 producing 245
Producer2 producing 189
Consumer1 consuming 386
Consumer2 consuming 240
Producer2 producing 740
Consumer1 consuming 982
Consumer2 consuming 453
Producer2 producing 264
Consumer1 consuming 878
Consumer2 consuming 228
Producer2 producing 686
Consumer1 consuming 189
Consumer2 consuming 740
Producer2 producing 761
Consumer1 consuming 264
Consumer2 consuming 686
Producer2 producing 586
Consumer1 consuming 761
Producer2 producing 847
Consumer1 consuming 586
Producer2 producing 161
Consumer1 consuming 847
Consumer1 consuming 161
        Producer2 finished
Consumer1 consuming 245
Producer1 producing 329
Consumer2 consuming 329
        Consumer1 terminating
        Consumer2 terminating
        Producer1 finished
*/
— End of Listing —

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.