Concurrent Programming Course

Assignment 3: Tea Shop Simulation

The Problem

The Owner of a Tea Shop suspects that the way in which the Shop is operated means that customers have to spend too much time waiting to be served, and so tend to go elsewhere instead. In order to evaluate the situation, a simulation of the Shop has been commissioned. Initially this simulation will simply run with text output describing the events as they occur in the Shop, and collect a minimal amount of statistical data.

Intention of assignment

The simulation is valuable to the Owner, but note that there are much better techniques for simulating than writing a concurrent program. The purpose of this assignment is to teach you to write a program in which synchronization and communication take place between several concurrent processes. It is intended to force you to solve (and not simply avoid) a range of interesting synchronisation problems.

Choice of programming language

In this assignment you must use JR.

Did you solve the exercise 4? It is very much recommended that you do that exercise before starting with this assignment. After you have completed that exercise you should have bits of JR code ready for this assignment.

Synchronisation constructs

For synchronisation you are only allowed to use message passing in JR. Anything else is strictly forbidden -- no semaphores, no monitors, etc. This also means that you are not allowed to use any shared variables except channels.


The Tea Shop

The Shop consists of a clock, the owner, a chef, and a number of customers. The Shop is operated by the owner and chef, whose job is to make and serve tea to the customers, who order at the Bar in a first-come-first-served manner. Each customer may only order a single cup at one time. The owner and chef can each serve only a single customer at a time, although others may be waiting to be served.

The owner and chef

  • There is one shared order queue served by both the owner and the chef.
  • The owner or the chef will refuse to serve any customer ordering after closing time.
  • If it is not closing time, the owner and chef serve customers independently. Customers can only order tea, which is served in disposable cups not tracked by the simulation.
  • The chef leaves at closing time. The owner will not leave the Shop until all others (customers and chef) have left the Shop.

    The owner

    • At ten-minutes before closing time the owner will be alerted by the Clock and calls last orders to warn the customers that closing time is soon.
    • The owner may finish serving any customer order he started before attending to the “last orders call
    • .
  • The owner and the chef may not use single-use reply channels that are passed in requests to them. Use the built-in randez-vous functionality of JR instead, which is call statement.

The Door

  • The customers enter the Shop at regular time intervals spread throughout the lifetime of the simulation.

The Customers

  • On entering the Shop, each customer will order a cup of tea, which will be served by either the owner or the chef.
  • When they've been served, customers will drink their tea. The drinking is assumed to take a set time.
  • When they've finished their tea, customers go back to the bar to order another cup. This goes on until the customer has drunk a set number of cups (configured at compile time), or the owner refuses to serve the customer because it is after closing time. In either case, the customer will leave the Shop straight away.
  • Some of the customers exhibit the following additional behavior: when they hear the owner call "last orders", if they are not currently drinking the last of their set number of cups, they will finish their current cup instantly and go to the bar to order one and only one more. Make sure to carefully read the details of this point in the “last orders” section.

The Clock

You do not have to write a clock yourself. You must use the following two classes. MyTime.java provides a class for representing times. Clock.jr implements the clock which keeps track of the time in the simulation. See source code documentation for how to use it.

The clock in the bar serves two purposes:

  • It will alert the owner of both “last orders” and “closing time”. The owner will alert his customers when it is time for last orders.
  • The clock serves and updates the current time that each process uses to print their actions.

The Statistics

At the end of the simulation, i.e. when all other processes have terminated cleanly, the owner must print the number of customers created, and entered/left the Shop. You may print additional statistics, but it is not a requirement:

  • Maximum/Average/Minimum waiting time for a customer when ordering.

  • Number of orders, accepted orders, refused orders.

  • Number of orders accepted after the last order call.

  • Number of customers that react to the last order call, and how many get accepted/refused.


The Last Orders Problem

Callback solution - recommended

Every customer that comes into the Shop says “Hello” to the owner and hands over a reference to itself (or a personal channel) to the owner (who stores it in some data structure). When they leave the Shop, they say goodbye to the owner, so he can remove that reference.

Unacceptable solutions

"Before you start drinking, calculate the time left until last call, and do not sleep longer than that".
You might think this is a good idea, but this way is not very realistic. In concurrent programming, you hardly ever know in advance when things will happen. Using this solution, you wouldn't learn anything useful.
The customers must be informed by the owner that it is time for last orders!
This solution is NOT acceptable.

Remember that you are only allowed to use message passing in this lab, so for example using shared variables other than channels is not an option!


Requirements

Submitting

When submitting, you must provide the following.

  • documentation.txt (the ASCII text file containing your documentation)
  • All your source code (*.java and *.jr) files necessary to compile and run your solution except Clock.jr and MyTime.java

Do not include uncessary files such as code generated by JR (the jrGen directory), hidden files (.*), or compiled java code (*.class files).

Documentation

You must document your solution with an ASCII text file. The documentation is intended as a description of your solution – do not translate your code into English. The documentation should include everything needed for easy understanding of the solution. In particular we demand that your documentation contains:

  • An overview of your solution by explaining what your classes do and how they relate to each other.
  • Is there any possibility of deadlock in your solution ? Why (not) ?

Source Code

  • The code structure has to be clear (even visually – use of indentation and newlines where appropriate) and should not be hidden in extensive documentation of trivialities ("this is an assignment of A to B"). Especially the call structure has to be either obvious or documented.
  • The code must use helpful variable, data structure and function names. If uncertain, use code comments to describe how the name is used at the point of declaration.
  • A process must not both send and receive from the same channel. For a given process and channel, the channel is either meant for call/send or receive/inni, not both.
  • No process without a class. Except for the main process (executing the main method when the program starts), the clock (which has been provided) processes, all processes must be in it's own class and created using the process syntax.
  • In order to see what is happening when running the simulation you must have output from the Customers, the owner, and the chef reporting all important events that occur.
  • All processes (except the ones in the clock, and the process executing the main method) must be given a name, which is used when printing from all processes. This will make it possible to see which process is actually printing, compared to just writing the name of the process one thinks is printing.

    You can set the name of a process like this: Thread.currentThread().setName("some name");

    Printing must contain the current time (from the clock) and which process is doing the printing. You must determine which process is doing the printing by using Thread.currentThread().getName().

    Here is an example of how it could look:

        public void print(String msg) {
            System.out.println(clock.getTime()  + ": " +
                               Thread.currentThread().getName() +
                               ": " + msg);
        }
        

You must not

  • Kill a thread or process. You may not use any of the following Java and/or JR methods/functions:
    • Thread.stop
    • Thread.resume
    • Thread.suspend
    • Thread.interrupt
    • setDaemon
    • JR.exit
  • If any of those primitives are found in your code, you will fail the assignment no matter the functionality of it.
  • Use any kind of polling or busy-waiting. Read this link on some examples of what we consider to be polling
  • Resolve communication with an all-purpose one-channel solution.

Observations

  • The present lab can be taken to mean that the owner and chef make tea in zero time. If so, the owner will be too fast, and there will be little interleaving of actions between the two serving guys; we want to see customers stuck at the bar.
  • Since we only serve tea, it would be nicer if customers were dynamic in their behavior. As of now, “..customer has drunk a set number of cups (configured at compile time)” suggests a constant behavior for all of them.
  • You may wish to explore these issues and change your code accordingly, but this is not required to pass the lab.

Tips and Tricks

  • Run your program without customers entering the Shop. This will work if your solution is correct. The solution should not be dependent on the events created by the customers.
  • Make sure you do not have any busy-waiting loops. Look through your solution carefully before handing it in. For example, you are likely to have busy waiting if you use []else-> inside of a while (some_condition) {inni ... } statement in JR.
  • It is not necessary for a processes to do multiple tasks at the same time. e.g when the owner takes an order, it is not necessary to listen for more messages to do other tasks while handling the order (which takes some time).
  • Use short delay times – there is no need for a simulation run to take more than 20–30 seconds.

Thanks

This is a simplification of the Pub lab, which was used in previous years of this course.

Last modified: Monday, 21-Jan-2013 16:14:32 CET
COMPUTER SCIENCE AND ENGINEERING - Chalmers University of Technology and Göteborg University
SE-412 96 Göteborg, Sweden - Tel: +46 (0)31- 772 1000