Search code examples
javamultithreadingparallel-processingexecutorserviceproducer-consumer

Concurrent Programming in Java. Trying to simulate a set of checkout counters


I'm trying to use Java to simulate a set of Checkout counters in a shopping center.

This is the assumption. There are 5 checkout counters. Like a real shopping center there is a line at each counter. Each counter services one customer at a time.

I tried to implement this as follows:

  1. Each customer is a class that runs a thread similar to the producer in the producer-consumer problem. The customers are part of a blockingqueue. I will somehow need a set of blocking queues to simulate 5 lines in front of the 5 checkout counters. How do I achieve this.

  2. The checkout counters have been defined as an Single thread Executor service. So now there will be 5 executors that will service one (producer) thread at a time. I have defined an arraylist of executors to simulate this group of 5.

  3. At the counter, one thread at a time from it's corresponding queue is being executed by the executor service (i.e consumer is consuming what the producer produces).

Is my logic correct?

I have some code but I'm not sure if my logic has been executed correctly by this code.

Please help. Cheers..

Code:

Checkout.java

package Supermarket;

import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Checkout implements Runnable
{
    public BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);

    public int checkout_number;
    public int item;

    public Random random;

    public Checkout(int checkout_number, BlockingQueue<Integer> item_queue)
    {
        this.checkout_number = checkout_number;
        this.item_queue = item_queue;

        random = new Random();
        System.out.println("\nCheckout Counter Number: "+checkout_number);
    }

    public void run()
    {
        while(true)
        {           
            if(item == -1)
            {
                System.out.println("Consumer finished");
                break;
            }
            else
            {
                try 
                {
                    item = item_queue.take();
                } 
                catch (InterruptedException e) 
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                System.out.println("\nConsumer has taken item ==> "+item);
                System.out.println("Scanning item");

                try 
                {
                    Thread.sleep(random.nextInt(5000));
                } 
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

}

Customer.java

    package Supermarket;

import java.util.*;
import java.util.concurrent.*;

public class Customer implements Runnable
{

    public int item;
    public int customer_number;
    public int i;
    public int item_count;

    public Random random = new Random();
    public BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);

    public Customer(int customer_number, BlockingQueue<Integer> item_queue)
    {
        this.customer_number = customer_number;
        this.item_queue = item_queue;
    }

    public void run()
    {
        item_count = random.nextInt(5);

        System.out.println("I am customer Number: "+customer_number+" and I have "+item_count+" items");

        for(i=0; i<item_count; i++)
        {
            try 
            {
                item_queue.put(random.nextInt(10));
            } 
            catch (InterruptedException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        try 
        {
            item_queue.put(-1);
        } 
        catch (InterruptedException e) 
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Driver.java

package Supermarket;

import java.util.concurrent.*;
import java.util.*;

public class Driver 
{
    public static BlockingQueue<Integer> item_queue = new ArrayBlockingQueue<Integer>(10);

    public static Random random = new Random();

    public static int customer_count;
    public static int checkout_count;
    public static int i;

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        customer_count = random.nextInt(4)+1;
//      checkout_count = 5;

        System.out.println("Total Number of Customers: "+customer_count+"\n");

            for(i=0; i<customer_count; i++)
            {
                Customer customer = new Customer(i+1, item_queue);
                Thread customer_thread = new Thread(customer);
                customer_thread.start();
            }

//          for(i=0; i<=checkout_count; i++)
//          {
//              Checkout checkout = new Checkout(1, item_queue);
//              Thread checkout_thread = new Thread(checkout);
//              checkout_thread.start();
//          }

//      System.out.println("\n\nProgram Terminates!\n\n");
    }

}

Solution

  • Your simulation may need to consider a few more features. For example you may want to consider some or all of the following design considerations:

    Customer

    Each customer has the following characteristics

    • A set of items to purchase.
      • All items are purchased in a single transaction, not one at a time
      • There may be 0..* items in a single transaction.
      • A 0-item transaction results in a receipt of $0.00.
    • Customer identification
    • Time of arrival at checkout line
    • Time of completed checkout transaction
    • Value of purchase transaction (i.e. a receipt)

    Checkout counter

    Each checkout counter has the following characteristics

    • A queue for customers waiting to check out.

    • The queue may have 0..* customers waiting to check out

    • The count of customers in a queue is available to each customer before entering the queue

    • Customers always choose the shortest available checkout queue

    • Once in a checkout queue all customers stay in that queue until their transaction is serviced.

    • Checkout Counter ID

    • A tally of customers served since the store opened

      • A 0 item transaction does not increment the tally of customers served
    • A total of all sales handled by the checkout counter

    Store Inventory

    The set of items available to purchase is the store inventory. Each item has the following characteristics

    • Item Id

    • Item cost

    The set of items a customer acquires to purchase contains only the Item ID for each item. A particular Item ID may appear more than once in a list of items a customer chooses to purchase.