Baran Topal

Baran Topal


April 2024
M T W T F S S
« Feb    
1234567
891011121314
15161718192021
22232425262728
2930  

Categories


Producer & Consumer in Java and .NET

baranbaran

Well, this snippet isĀ from my old backup and let’s have a look for producer-consumer paradigm in action (in Java and .NET):

Have a look how join works in Java: http://www.barantopal.com/technology/multithreading-and-join/



import java.util.Stack;
import java.util.concurrent.atomic.AtomicInteger;
 
/**
 * 1 producer and 3 consumers producing/consuming 10 items
 * 
 * @author pt
 * 
 */
public class ProducerConsumer {
 
        Stack items = new Stack();
        final static int NO_ITEMS = 10;
 
        public static void main(String args[]) {
                ProducerConsumer pc = new ProducerConsumer();
                Thread t1 = new Thread(pc.new Producer());
                Thread t2 = new Thread(pc.new Consumer());
                Thread t3 = new Thread(pc.new Consumer());
                Thread t4 = new Thread(pc.new Consumer());
                t1.start();
                try {
                        Thread.sleep(100);
                } catch (InterruptedException e1) {
                        e1.printStackTrace();
                }
                t2.start();
                t3.start();
                t4.start();
                try {
                        t2.join();
                        t3.join();
                        t4.join();
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
        }
 
        class Producer implements Runnable {
 
                public void produce(int i) {
                        System.out.println("Producing " + i);
                        items.push(new Integer(i));
                }
 
                @Override
                public void run() {
                        int i = 0;
                        // produce 10 items
                        while (i++ < NO_ITEMS) {
                                synchronized (items) {
                                        produce(i);
                                        items.notifyAll();
                                }
                                try {
                                        // sleep for some time, 
                                        Thread.sleep(10);
                                } catch (InterruptedException e) {
                                }
                        }
                }
        }
 
        class Consumer implements Runnable {
 
                AtomicInteger consumed = new AtomicInteger();
 
                public void consume() {
                        if (!items.isEmpty()) {
                                System.out.println("Consuming " + items.pop());
                                consumed.incrementAndGet();
                        }
                }
 
                private boolean theEnd() {
                        return consumed.incrementAndGet() >= NO_ITEMS;
                }
 
                @Override
                public void run() {
                        while (!theEnd()) {
                                synchronized (items) {
                                        while (items.isEmpty() && (!theEnd())) {
                                                try {
                                                        items.wait(10);
                                                } catch (InterruptedException e) {
                                                        Thread.interrupted();
                                                }
                                        }
                                        consume();
 
                                }
                        }
                }
        }
}

Let’s do the similar in .NET:


using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleApp_ProducerConsumer
{
    class Program
    {
        static void Main(string[] args)
        {
            Object lockObj = new object();
            Queue queue = new Queue();
            Producer p = new Producer(queue);
            Comsumer c1 = new Comsumer(queue, lockObj, "c1");
            Comsumer c2 = new Comsumer(queue, lockObj, "c2");

            Thread t1 = new Thread(c1.consume);
            Thread t2 = new Thread(c2.consume);
            t1.Start();
            t2.Start();

            Thread t = new Thread(p.produce);
            t.Start();
            // keep console window open
            Console.ReadLine();
        }
    }

    public class Producer
    {
        Queue queue;
        int productionCycleCounter;
        public Producer(Queue queue)
        {
            this.queue = queue;
        }

        public void produce()
        {
            while (productionCycleCounter < 100) 
            {
                productionCycleCounter += 1;// increase counter
                string item = "item" + productionCycleCounter;
                queue.Enqueue(item);
                Console.WriteLine("Producing {0}", item);
            }
        }
    }

    public class Comsumer
    {
        Queue queue;
        Object lockObject;
        string name;
        public Comsumer(Queue queue, Object lockObject, string name)
        {
            this.queue = queue;
            this.lockObject = lockObject;
            this.name = name;
        }

        public void consume()
        {
            Thread.Sleep(500);
            string item;
            while (true)
            {
                lock (lockObject)
                {
                    if (queue.Count == 0)
                    {
                        continue;
                    }
                    item = queue.Dequeue();
                    Console.WriteLine(" {0} Comsuming {1}", name, item);
                }
            }
        }
    }

}