Tải bản đầy đủ (.pdf) (105 trang)

discrete event simulation in java

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (396.49 KB, 105 trang )

1
Discrete Event Simulation in Java
Keld Helsgaun
E-mail:
Department of Computer Science
Roskilde University
DK-4000 Roskilde, Denmark
Abstract
This report describes javaSimulation, a Java package for
process-based discrete event simulation. The facilities of the
package are based on the simulation facilities provided by the
programming language SIMULA. The design of the package
follows the SIMULA design very closely. The package is easy to
use and relatively efficient. In addition, Java packages for co-
routine sequencing, event-based simulation and activity-based
simulation are presented.
Keywords: simulation, Java, process, discrete event, coroutine
1. Introduction
The Java platform comes with several standard packages. No package, how-
ever, is provided for discrete event simulation. This is unfortunate since dis-
crete event simulation constitutes an important application area of object ori-
ented programming. This fact has convincingly been demonstrated by
SIMULA, one of the first object-oriented programming languages [1][2][3].
SIMULA provides the standard class SIMULATION, a very powerful tool
for discrete event simulation. A simulation encompasses a set of interacting
processes. A process is an object associated with a sequence of activities or-
dered logically in simulated time. Each process has its own life cycle and may
undergo active and inactive phases during its lifetime.
2
Processes represent the active entities in the real world, e.g., customers in a
supermarket. Thus, the process concept may be used to describe systems in a


natural way.
This report describes javaSimulation, a Java package for process-based
discrete event simulation. The package may be seen as an implementation of
class SIMULATION in Java. In addition to the simulation facilities, the pack-
age also includes the facilities for list manipulation and random number
drawing as found in SIMULA.
When designing the package, great emphasis has been put into following the
SIMULA design as closely as possible. The advantage of this approach is that
the semantics of facilities are well-known and thoroughly tested through
many years’ use of SIMULA. A SIMULA user should easily learn to use the
package.
The rest of this report is structured as follows.
Chapter 2 provides a short introduction to discrete event simulation by means
of a concrete example, a car wash simulation. The example is used to demon-
strate the use of three different approaches to discrete event simulation: event-
based, activity-based and process-based. In relation to these approaches sev-
eral packages have been developed. These packages are described from the
user’s point of view and their use is demonstrated by means of the car wash
example.
Implementing a process-based simulation package in Java is not a trivial task.
A process must be able to suspend its execution and have it resumed at some
later time. In other words, a process should be able to act like a coroutine.
Chapter 3 describes the development of a package, javaCoroutine, for
coroutine sequencing in Java. The package provides the same coroutine fa-
cilities as can be found in SIMULA. Its implementation is based on Java’s
threads.
This coroutine package is then used in Chapter 4 for the implementation of a
package for process-based simulation, javaSimulation.
javaSimulation is evaluated in Chapter 5, and some conclusions are
made in Chapter 6.

The appendices contain Java source code and documentation.
3
2. Discrete event simulation in Java
Simulation may be defined as the experimentation with a model in order to
obtain information about the dynamic behavior of a system. Instead of ex-
perimenting with the system, the experiments are performed with a model of
the system. Simulation is typically used when experimentation with the real
system is too expensive, too dangerous, or not possible (e.g., if the real sys-
tem does not exist).
The system components chosen for inclusion in the model are termed entities.
Associated with each entity are zero or more attributes that describe the state
of the entity. The collection of all these attributes at any given time defines the
system state at that time.
There are three categories of simulation models, defined by the way the sys-
tem state changes:
• Continuous: the state varies continuously with time. Such systems are
usually described by sets of differential equations.
• Discrete: the state changes only at discrete instances of time (event times).
4
• Combined continuous and discrete: the state changes instantaneously at
event times; in between consecutive event times the system state may vary
continuously [4].
In this report we will only consider so-called discrete event simulation. In
discrete event simulation the model is discrete, and the simulated clock always
jumps from one event time to the most imminent event time. At each event
time the corresponding action (state change) is performed, and simulated time
is advanced to the next time when some action is to occur. Thus, discrete
event simulation assumes that nothing happens between successive state
changes.
In order to make the following description easier to comprehend, a concrete

simulation example will now be presented.
2.1 The car wash problem
This example has been taken from [1].
A garage owner has installed an automatic car wash that services cars one at a
time. When a car arrives, it goes straight into the car wash if this is idle; oth-
erwise, it must wait in a queue. The car washer starts his day in a tearoom
and return there each time he has no work to do. As long as cars are waiting,
the car wash is in continuous operation serving on a first-come, first-served
basis. All cars that have arrived before the garage closes down are washed.
Each service takes exactly 10 minutes. The average time between car arrivals
has been estimated at 11 minutes.
The garage owner is interested in predicting the maximum queue length and
average waiting time if he installs one more car wash and employs one more
car washer.
5
2.2 Three approaches for discrete event simulation
There are basically three approaches that can be used for discrete event simu-
lation: the event-based, the activity-based and the process-based approach [5].
(1) The event-based approach
In the event-based approach the model consists of a collection of events. Each
event models a state change and is responsible for scheduling other events
that depend on that event.
Each event has associated an event time and some actions to be executed
when the event occurs.
In the car wash problem the arrival of a car is an example of an event. Actions
associated with this event are the inclusion of the car into the waiting line and
the scheduling of the next car arrival.
Event-based simulation is the simplest and most common implementation
style of discrete event simulation because it can be implemented in any pro-
gramming language.

(2) The activity-based approach
In the activity-based approach the model consists of a collection of activities.
Each activity models some time-consuming action performed by an entity.
Each activity has associated a starting condition, some actions to be executed
when the activity starts, the duration of the activity, and some actions to be
executed when the activity finishes.
In the car wash problem the washing of a car is an example of an activity. The
condition for starting this activity is that one of car washers is idle and the
waiting line is not empty. When the activity starts, an idle car washer is re-
moved from the tearoom, and the first waiting car is removed from the wait-
ing line. The duration of the activity is 10 units of simulated time. When it
ends, the car washer is put back into the tearoom.
Whilst the activity approach is relatively easy to understand, it normally suf-
fers from poor execution efficiency compared to the event-based approach.
6
(3) The process-based approach
In the process-based approach the model consists of a collection of processes.
Each process models the life cycle of an entity and is a sequence of logically
related activities ordered in time.
In the car wash problem a car is an example of a process. Each car performs
the following sequence of activities: wait in queue, get washed.
Since processes resemble objects in the real world, process-based simulation
is often easy to understand. Implementation, however, is not easy and exe-
cution efficiency may be poor if the implementation is not done properly.
The figure below illustrates the relation between the concepts event, activity
and process.
In the remaining part of this chapter we will show how the car wash problem
can be solved in Java using each of the three simulation approaches.
event
process

time
wait in queue
get washed
activity
event event
activity
7
2.3 Solving the car wash problem by event-based simulation
To provide a simple tool for event-based simulation a small Java package
called simulation.event has been developed.
When using this package the events of a model are described in one or more
subclasses of class Event. An outline of this class is shown below.
public abstract class Event {
protected abstract void actions();
public void schedule(double evTime);
public void cancel();
public static double time();
public static void runSimulation(double period);
public static void stopSimulation();
}
The actions method represents the actions associated with the event. These
actions will be executed when the event occurs.
An event is scheduled to occur at a specified point in simulated time by calling
its schedule method. The desired event time is passed as an argument to
the method.
A scheduled event may be cancelled by calling its cancel method.
The time method returns the current simulated time.
The runSimulation method is used to run a simulation for a specified pe-
riod of simulated time. Time will start at 0 and jump from event time to event
time until either this period is over, there are no more scheduled events, or the

stopSimulation method is called.
Below we will show how the package may be used for solving the car wash
problem. For this purpose we will exploit two other packages, simset and
random. The simset package provides the same facilities for list manipu-
lation as class SIMSET of SIMULA. The random package provides all of
SIMULA’s methods for drawing random numbers. The source code and
documentation of these two packages can be found in the appendices A, B,
C and D.
8
We will represent the entities of the system (car washers and cars) by the two
classes CarWasher and Car.
class CarWasher extends Link {}
class Car extends Link {
double entryTime = time();
}
Both classes extend the Link class from the simset package. This has the
effect that any object of these classes is capable of being a member of a
queue. Thus, a CarWasher may be put into a queue of idle car washers, and
a Car may be put into a line of waiting cars.
The attribute entryTime of the Car class is used for each Car to record the
time it entered the garage.
The two queues are defined using the Head class of the simset package:
Head tearoom = new Head();
Head waitingLine = new Head();
Next, we define the following events:
• A car arrives
• A car washer starts washing a car
• A car washer finishes washing a car
These events are specified in three subclasses of class Event.
A car arrival is described in class CarArrival as shown below.

class CarArrival extends Event {
public void actions() {
if (time() <= simPeriod) {
Car theCar = new Car();
theCar.into(waitingLine);
int qLength = waitingLine.cardinal();
if (maxLength < qLength)
maxLength = qLength;
if (!tearoom.empty())
new StartCarWashing().schedule(time());
new CarArrival().schedule(
time() + random.negexp(1/11.0));
}
}
}
9
The actions method specifies what happens when a car arrives at the ga-
rage. Unless the garage has closed, a Car is created and put into the waiting
line. Next, if any car washer is idle (is waiting in the tearoom), the starting of
a wash is scheduled to occur immediately. Finally the next car arrival is
scheduled using the random package. Here, it is assumed that the number of
minutes between arrivals is distributed according to a negative exponential
distribution with a mean of 11 minutes.
Actually, it is not necessary for a CarArrival object to create a new
CarArrival object before it finishes. It could simply reschedule itself by
executing the following statement
schedule(time() + random.negexp(1.0/11.0));
The starting of a car wash is described in class StartCarWash shown be-
low.
class StartCarWashing extends Event {

public void actions() {
CarWasher theCarWasher =
(CarWasher) tearoom.first();
theCarWasher.out();
Car theCar = (Car) waitingLine.first();
theCar.out();
new StopCarWashing(theCarWasher, theCar).
schedule(time() + 10);
}
}
When this event takes place, an idle car washer is removed from the tearoom,
and the first waiting car is removed from the waiting line.
A car wash takes 10 minutes. Accordingly, a StopCarWashing event is
scheduled to occur 10 time units later.
10
Class StopCarWashing is shown below.
class StopCarWashing extends Event {
CarWasher theCarWasher;
Car theCar;
StopCarWashing(CarWasher cw, Car c)
{ theCarWasher = cw; theCar = c; }
public void actions() {
theCarWasher.into(tearoom);
if (!waitingLine.empty())
new StartCarWashing().schedule(time());
noOfCustomers++;
throughTime += time() - theCar.entryTime;
}
}
When a car washer has finished washing a car, he goes into the tearoom.

However, if there are cars waiting to be washed, a new StartCarWashing
event is scheduled to occur at once. So he will have a break, unless another
idle car washer can do the job.
In order to make a report when the simulation has ended the following vari-
ables are updated:
noOfCustomers: the number of cars through the system
throughTime: the sum of elapsed times of the cars
11
The simulation program is shown below (excluding the classes described
above). Note the use of inner classes.
import simulation.event.*;
import simset.*;
import random.*;
public class CarWashSimulation extends Simulation {
double simPeriod = 200;
Head tearoom = new Head();
Head waitingLine = new Head();
Random random = new Random(5);
int noOfCustomers, maxLength;
double throughTime;
CarWashSimulation(int n) {
noOfCarWashers = n;
for (int i = 1; i <= noOfCarWashers; i++)
new CarWasher().into(tearoom);
new CarArrival().schedule(0);
runSimulation(simPeriod + 1000000);
report();
}
void report() { }
class CarWasher extends Link {}

class Car extends Link { }
class CarArrival extends Event { }
class StartCarWashing extends Event { }
class StopCarWashing extends Event { }
public static void main(String args[]) {
new CarWashSimulation(1);
new CarWashSimulation(2);
}
}
The main method of the program performs two simulations, the first with
one car washer, the second with two car washers.
When a CarWashSimulation object is created, all car washers are put
into the tearoom, the first car is scheduled to arrive immediately, and the sys-
tem is simulated for a specified period of time.
The parameter passed to the runSimulation method has to do with fin-
ishing-off the simulation. When simPeriod time units have passed the ga-
rage closes and no more cars arrive, but all cars in the queue at that time will
eventually be served. In the program simPeriod has been set to 200.
12
When a simulation has finished, the method report is called in order to
write statistics generated by the model. This method appears as follows:
void report() {
System.out.println(noOfCarWashers
+ " car washer simulation");
System.out.println("No.of cars through the system = "
+ noOfCustomers);
java.text.NumberFormat fmt =
java.text.NumberFormat.getNumberInstance();
fmt.setMaximumFractionDigits(2);
System.out.println("Av.elapsed time = "

+ fmt.format(throughTime/noOfCustomers));
System.out.println("Maximum queue length = "
+ maxLength + “\n”);
}
A run of the program produced the following output:
1 car washer simulation
No.of cars through the system = 22
Av.elapsed time = 30.22
Maximum queue length = 5
2 car washer simulation
No.of cars through the system = 22
Av.elapsed time = 10.74
Maximum queue length = 1
The implementation of this package is straightforward. All scheduled events
are held in a list (SQS) ordered by their associated event times. As long as
there are more scheduled events, and the simulation period is not over, the
first event of SQS is removed, time is updated to this event time, and the ac-
tions of this event are executed.
This algorithm is implemented in the runSimulation method shown be-
low.
public static void runSimulation(double period) {
while (SQS.suc != SQS) {
Event ev = SQS.suc;
if ((time = ev.eventTime) > period) break;
ev.cancel();
ev.actions();
}
stopSimulation();
}
The complete source code of the package is provided in Appendix E.

13
2.4 Solving the car wash problem by activity-based simulation
The activity-based approach tries to capture the notion of connected start and
finish events, clustering descriptions of actions to be executed at the start and
finish of some time-consuming activity. The programmer must specify condi-
tions under which such clusters of actions will occur.
Every activity should be associated with a start condition, a specification of
the duration of the activity, and some start and finish actions. The start actions
of an activity will be executed as soon as its associated condition becomes
true. The finish actions will be executed when the activity ends (after a time
period equal to the duration of the activity).
To provide a simple tool for activity-based simulation, a small Java package
called simulation.activity has been developed.
When using this package the activities of a model are described in one or
more subclasses of class Activity. An outline of this class is given below.
public abstract class Activity {
protected abstract boolean condition();
protected abstract void startActions();
protected abstract double duration();
protected abstract void finishActions();
public static double time();
public static void runSimulation(double period);
public static void stopSimulation();
}
In order to specify an activity, all four abstract methods should be overridden
in subclasses of class Activity.
The time method returns the current simulated time.
The runSimulation method is used to run a simulation for a specified pe-
riod of simulated time. Time will start at 0 and jump from event time to event
time until either this period is over, there are no more actions to be executed,

or the stopSimulation method is called.
Below we will show how the package may be used for solving the car wash
problem.
14
Queues, car washers and cars are represented as follows:
Head tearoom = new Head();
Head waitingLine = new Head();
class CarWasher extends Link {}
class Car extends Link {
double entryTime = time();
}
The dynamics of the system may be described by the following activities in-
volving the passing of time:
• Washing a car
• Waiting for the next car to arrive
These activities are specified in two subclasses of class Activity.
The washing of a car is described in class CarWashing shown below.
class CarWashing extends Activity {
Car theCar;
CarWasher theCarWasher;
CarWashing(Car c) { theCar = c; }
public boolean condition() {
return theCar == (Car) waitingLine.first() &&
!tearoom.empty();
}
public void startActions() {
theCar.out();
theCarWasher = (CarWasher) tearoom.first();
theCarWasher.out();
}

public double duration() {
return 10;
}
public void finishActions() {
theCarWasher.into(tearoom);
noOfCustomers++;
throughTime += time() - theCar.entryTime;
}
}
15
In order for the washing of a car to start, the car must be in front of the wait-
ing line and there must be an idle car washer (i.e., the tearoom must not be
empty). When the washing activity is started the car is removed from the
waiting line and one of the idle car washers is removed from the tearoom. The
wash takes 10 minutes after which the car washer goes back to the tearoom.
The class CarArrival shown below models the time-passing activity of
waiting for the next car to arrive.
class CarArrival extends Activity
public boolean condition() {
return true;
}
public void startActions() {
Car theCar = new Car();
theCar.into(waitingLine);
new CarWashing(theCar);
int qLength = waitingLine.cardinal();
if (maxLength < qLength)
maxLength = qLength;
}
public double duration() {

return random.negexp(1/11.0);
}
public void finishActions() {
if (time() <= simPeriod)
new CarArrival();
}
}
A CarArrival activity starts immediately when created. This is accom-
plished by letting the condition method return true. The activity starts
by inserting a new car as the last member of the waiting line and creates a
CarWashing activity for this car. After a time period, chosen at random
from a negative exponential distribution, the activity finishes by generating a
new CarArrival activity.
16
The simulation program is shown below (excluding the classes described
above).
import simulation.activity;
import simset.*;
import random.*;
public class CarWashSimulation extends Simulation {
int noOfCarWashers;
double simPeriod = 200;
Head tearoom = new Head();
Head waitingLine = new Head();
Random random = new Random(5);
int noOfCustomers, maxLength;
double throughTime;
CarWashSimulation(int n) {
noOfCarWashers = n;
for (int i = 1; i <= noOfCarWashers; i++)

new CarWasher().into(tearoom);
new CarArrival();
runSimulation(simPeriod + 1000000);
report();
}
void report() { }
class CarWasher extends Link {}
class Car extends Link { }
class CarWashing extends Activity { }
class CarArrival extends Activity { }
public static void main(String args[]) {
new CarWashSimulation(1);
new CarWashSimulation(2);
}
}
The main method of the program performs two simulations, the first with
one car washer, the second with two car washers. Each simulation is per-
formed by the creation of an object of class CarWashSimulation (a sub-
class of class Simulation).
The program produces the same output as the program in Section 2.3.
17
The implementation of this package is straightforward. All activities waiting
to start are held in a list, waitList. All activities that are scheduled to finish
are held in a list, SQS, ordered by their associated finish times. At each event
time, the wait list is examined to see whether any activity is eligible to start. If
so, the activity is removed from the list, its start actions are executed, and a
finish event is scheduled to occur when the activity finishes. When no more
activities are eligible to start, time advances to the next imminent event, and
the associated finish actions are executed. This continues until the simulation
ends.

This algorithm is implemented in the runSimulation method shown be-
low.
public static void runSimulation(double period) {
while (true) {
for (Activity a = waitList.suc;
a != waitList;
a = a.suc) {
if (a.condition()) {
a.cancel();
a.schedule(time + a.duration());
a.startActions();
a = waitList;
}
}
if (SQS.suc == SQS)
break;
Activity a = SQS.suc;
time = a.eventTime;
a.cancel();
if (time > period)
break;
a.finishActions();
}
stopSimulation();
}
The complete source code of the package is provided in Appendix G.
18
2.5 Solving the car wash problem by mixed event-activity-based
simulation
The different simulation approaches are not mutually exclusive. Mixed ap-

proaches may also be used.
In this section we will demonstrate how the event-approach and ingredients of
the activity-approach may be combined into one single approach. For this
purpose we will extend the event concept with the following definitions:
A time event is an event scheduled to occur at a specified point in time.
A state event is an event scheduled to occur when the state of the sys-
tem fulfills a specified condition (a so-called state condition).
These two event types are used to model the dynamics of a system.
In order to provide a tool for using this simulation approach a small Java
package called simulation.events has been developed.
When using this package the events of a model are described in one or more
subclasses of the classes TimeEvent and StateEvent, which themselves
are subclasses of the abstract class Event.
The class hierarchy is shown below.
public abstract class Event {
protected abstract void actions();
public static double time();
public static void runSimulation(double period);
public static void stopSimulation();
}
public abstract class TimeEvent extends Event {
public void schedule(double evTime);
}
public abstract class StateEvent extends Event {
protected abstract boolean condition();
public void schedule();
}
19
The meaning and usage of the methods should be clear from the previous
sections. Below we will show how the package can be used for solving the

car wash problem.
Queues, car washers and cars are specified as in the previous two sections,
i.e.:
Head tearoom = new Head();
Head waitingLine = new Head();
class CarWasher extends Link {}
class Car extends Link {
double entryTime = time();
}
We will use the same three events as were used in the event-based approach:
• A car arrives (carArrival)
• A car washer starts washing a car (startCarWashing)
• A car washer finishes washing a car (stopCarWashing)
However, in this mixed approach we must also specify which of these events
are time events, and which are state events.
It is easy to see that the arrival of a car and the finishing of a car wash are
both time events. On the other hand, the starting of a car wash must be a state
event, since its time of occurrence can not be predetermined.
This leads to the following class declarations for the three event types:
class CarArrival extends TimeEvent {
public void actions() {
if (time() <= simPeriod) {
Car theCar = new Car();
theCar.into(waitingLine);
int qLength = waitingLine.cardinal();
if (maxLength < qLength)
maxLength = qLength;
new StartCarWashing(theCar).schedule();
schedule(time() + random.negexp(1/11.0));
}

}
}
20
class StartCarWashing extends StateEvent {
Car theCar;
CarWashing(Car c) { theCar = c; }
public boolean condition() {
return theCar == (Car) waitingLine.first() &&
!tearoom.empty();
}
public void actions() {
theCar.out();
CarWasher theCarWasher =
(CarWasher) tearoom.first();
theCarWasher.out();
new StopCarWashing(theCarWasher, theCar).
schedule(time() + 10);
}
}
class StopCarWashing extends TimeEvent {
CarWasher theCarWasher;
Car theCar;
StopCarWashing(CarWasher cw, Car c)
{ theCarWasher = cw; theCar = c; }
public void actions() {
noOfCustomers++;
throughTime += time() - theCar.entryTime;
theCarWasher.into(tearoom);
}
}

}
The simulation program follows the same pattern as used in the previous two
sections. See Appendix J for the complete source code.
The implementation of this package is straightforward. All scheduled state
events are held in a list, waitList, and all scheduled time events are held in
a list, SQS, ordered by their associated event times. At each event time, the
wait list is examined to see whether any state event has its condition fulfilled.
If so, the event is removed from the list and its actions are executed. When no
more state events occur, time advances to the next imminent time event, and
the associated actions of this time event are executed This continues until the
simulation ends.
21
This algorithm is implemented in the runSimulation method as shown
below.
public static void runSimulation(double period) {
while (true) {
for (StateEvent a = (StateEvent) waitList.suc;
a != waitList;
a = (StateEvent) a.suc) {
if (a.condition()) {
a.cancel();
a.actions();
a = waitList;
}
}
if (SQS.suc == SQS)
break;
TimeEvent ev = (TimeEvent) SQS.suc;
time = ev.eventTime;
ev.cancel();

if (time > period)
break;
ev.actions();
}
stopSimulation();
}
The complete source code of the package is provided in Appendix I.
22
2.6 Solving the car wash problem by process-based simulation
The process-based approach is often the easiest to use. In this approach the
active entities of a system are modeled in a very natural way. A process de-
scribes the life cycle of an entity of the system. Any process is associated
with actions to be performed by the process during its lifetime. A process
may be suspended temporarily and may be resumed later from where it left
off.
In order to provide a tool for the process-based approach a Java package
called javaSimulation has been developed.
When using this package the processes of a model are described in one or
more subclasses of class Process. An outline of this class is given below.
In this outline only facilities that are actually used in solving the car wash
problem have been included. A more comprehensive version is given at the
end of this section.
public abstract class Process extends Link {
protected abstract void actions();
public static double time();
public static void activate(Process p);
public static void hold(double t);
public static void passivate();
public static void wait(Head q);
}

Since Process is a subclass of Link, each process has the capability of
being a member of a two-way list. This is useful, for example, when proc-
esses must wait in a queue. The javaSimulation package includes all the
list manipulation facilities of the simset package.
The actions method represents the actions associated with a process.
The time method returns the current simulated time.
The activate method is used to make a specified process start executing its
actions.
The hold method suspends the execution of the calling process for a speci-
fied period of time.
The passivate method suspends the execution of the calling process for an
unknown period of time. Its execution may later be resumed by calling
activate with the process as argument.
23
The wait method suspends the calling process and adds it to a queue.
Below we will show how the package can be used for solving the car wash
problem.
First, the processes are identified and their actions are described in subclasses
of class Process by overriding the actions method
A car washer is described in the following subclass of Process:
class CarWasher extends Process {
public void actions() {
while (true) {
out();
while (!waitingLine.empty()) {
Car served =
(Car) waitingLine.first();
served.out();
hold(10);
activate(served);

}
wait(tearoom);
}
}
}
The actions of a car washer are contained in an infinite loop (the length of the
simulation is supposed to be determined by the main program). Each time a
car washer is activated, he leaves the tearoom and starts serving the cars in the
waiting line. He takes the first car out of the waiting line, washes it for ten
minutes before he activates the car. The car washer will continue servicing, as
long as there are cars waiting in the queue. If the waiting line becomes empty,
he returns to the tearoom and waits.
24
A car may be described by the following subclass of Process:
class Car extends Process {
public void actions() {
double entryTime = time();
into(waitingLine);
int qLength = waitingLine.cardinal();
if (maxLength < qLength)
maxLength = qLength;
if (!tearoom.empty())
activate((CarWasher) tearoom.first());
passivate();
noOfCustomers++;
throughTime += time() - entryTime;
}
}
On arrival each car enters the waiting line and, if the tearoom is not empty, it
activates the idle car washer in the tearoom. The car then passively waits until

it has been washed. When the car has been washed (signaled by an activation
by the car washer), it leaves the system.
The following subclass of Process is used to make the cars arrive at the ga-
rage with an average inter-arrival time of 11 minutes:
class CarGenerator extends Process {
public void actions() {
while (time() <= simPeriod) {
activate(new Car());
hold(random.negexp(1/11.0));
}
}
}
All random drawing facilities of the random package have been included in
the javaSimulation package. In the present simulation the inter-arrival
times of the cars are distributed according to a negative exponential distribu-
tion.
25
The simulation program is shown below (excluding the classes described
above).
import javaSimulation.*;
import javaSimulation.Process;
public class CarWashSimulation extends Process {
int noOfCarWashers;
double simPeriod = 200;
Head tearoom = new Head();
Head waitingLine = new Head();
Random random = new Random(5);
double throughTime;
int noOfCustomers, maxLength;
CarWashSimulation(int n) {

noOfCarWashers = n;
}
public void actions() {
for (int i = 1; i <= noOfCarWashers; i++)
new CarWasher().into(tearoom);
activate(new CarGenerator());
hold(simPeriod + 1000000);
report();
}
void report() { }
class Car extends Process { }
class CarWasher extends Process { }
class CarGenerator extends Process { }
public static void main(String args[]) {
activate(new CarWashSimulation(1));
activate(new CarWashSimulation(2));
}
}
The program imports all classes of the javaSimulation package. Note,
however, that class Process must be imported explicitly in order to avoid
the name conflict caused by the co-existence of the class Process of the
java.lang package.
The main method of the program performs two simulations, the first with
one car washer, the second with two car washers.
Each simulation is performed by the creation and activation of an object of
class CarWashSimulation.

×