You have enough memory for 5 documents. There are no
documents initially, but documents are created at random intervals
that vary uniformly between 0 and 8 seconds. A printing process takes
a random interval between 0 and 10 seconds to print a document, after
which the memory holding the document becomes available.
Write a program that visually displays what percentage of the
memory is free and what percentage of memory has documents in it for
one minute of real time. After one minute, the program should
terminate.
Detailed Description
-------- -----------
You will need to create the following objects and classes:
Objects Classes Comments
------- ------- --------
random number Randgen The necessary code is available in
generator the file /export/home/os/Randgen.java
An interface is available in the file
/export/home/os/RandomGenerator.java
semaphores Semaphore You can use the code on p. 258 of the
(2, one for text. Note that "acquire" is really
documents the P operation and "release" is the V
and one for operation.
memory)
Producer (1) Producer A simulation of the document producer
process.
Consumer (1) Consumer A simulation of the document printer
process process.
Timer (1) Timer A timer that runs for one minute.
Things to know
-----
1. Since the random number generator classes and the Semaphore class
have already been provided, only the Producer, Consumer, and Timer
classes are really needed. All three classes are on-going
processes. Java handles this through the Thread class and the
Runnable Interface.
Here is a supporting class written for the solution:
/*
* *
*/
/**
*
*
*/
public abstract class Job implements Runnable {
protected static Semaphore memory;
protected static Semaphore documents;
public static final int maxMemory = 5;
public Job() {
memory = new Semaphore(maxMemory);
documents = new Semaphore(0);
}
public void start() {
(new Thread(this)).start();
}
public abstract void run();
}
The purpose of the Job class is to model the things that
Producers and Consumers have in common. Because Job implements the
Runnable interface, it (and any class that inherits from it) can run
as a Java thread concurrently with other threads. While the Timer
class doesn't inherit from Job, it too will have to implement the
Runnable interface.
The Runnable interface requires that the implementing class
have a "public void run()" method. This is the "program" that the
thread executes. Since Job doesn't have a program by itself, this
method and the whole class must be "abstract", which means that Job is
simply intended as a base class for other classes to inherit from
You have to make sure that the number of documents are the same
for both the producer and consumer. The same is true of the amount of
free memory. Putting the variables in the Job class is the most
elegant way to solve the problem. Because these variables are
protected, they are available to both Producer and Consumer (which
inherit from Job). Because the variables are static, there is a
unique copy of each variable for the entire Job class.
As a practical matter, any class implementing the Runnable
interface must have a "start" method. The start method's job is start
a single thread (repeated calls will started multiple threads). The
Job class start method is pretty much a universal version. This means
you won't have to put start methods in the Producer and Consumer
classes (so they will use the Job start method by default). The Timer
class will need a start method; you can just cut and paste the Job
start method to the Timer class.
2. A program can be delayed by using the Thread.sleep method. Notice
that "sleep" is a static method of the Thread class, so it is invoked
with the class name (Thread), not the name of an object. The argument
is in milliseconds:
Thread.sleep(10);
would delay the program by 10 milliseconds = 10/1000 seconds = .01
seconds.
The Java compiler will insist that you either catch or throw an
InterruptedException if you use the sleep method:
try {
Thread.sleep(100);
}
catch (InterruptedException ie) {
ie.printStackTrace();
}
3. To display the percentage of memory and documents you have, a
JProgressBar is ideal. To use them:
// main class
JProgressBar amtMemory;
JProgressBar numDocuments;
...
// In the constructor
// Set minimum and maximum variable values
amtMemory = new JProgressBar(0,Job.maxMemory);
numDocuments = new JProgressBar(0,Job.maxMemory);
// Set initial values
amtMemory.setValue(Job.maxMemory);
numDocuments.setValue(0);
// Display the percentage as a String
amtMemory.setStringPainted(true);
numDocuments.setStringPainted(true);
// The JProgress bars are visible
amtMemory.setVisible(true);
numDocuments.setVisible(true);
...
// Anyplace that the variables change
amtMemory.setValue(newAmountOfFreeMemory);
numDocuments.setValue(newNumberOfDocuments); |